mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 17:12:03 +00:00
Merge remote-tracking branch 'upstream/master' into feature/attach-partition-local
This commit is contained in:
commit
c947280dfc
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -93,7 +93,7 @@
|
||||
url = https://github.com/ClickHouse-Extras/libunwind.git
|
||||
[submodule "contrib/simdjson"]
|
||||
path = contrib/simdjson
|
||||
url = https://github.com/ClickHouse-Extras/simdjson.git
|
||||
url = https://github.com/simdjson/simdjson.git
|
||||
[submodule "contrib/rapidjson"]
|
||||
path = contrib/rapidjson
|
||||
url = https://github.com/ClickHouse-Extras/rapidjson
|
||||
@ -221,3 +221,6 @@
|
||||
[submodule "contrib/NuRaft"]
|
||||
path = contrib/NuRaft
|
||||
url = https://github.com/ClickHouse-Extras/NuRaft.git
|
||||
[submodule "contrib/datasketches-cpp"]
|
||||
path = contrib/datasketches-cpp
|
||||
url = https://github.com/ClickHouse-Extras/datasketches-cpp.git
|
||||
|
@ -248,19 +248,27 @@ if (ARCH_NATIVE)
|
||||
set (COMPILER_FLAGS "${COMPILER_FLAGS} -march=native")
|
||||
endif ()
|
||||
|
||||
if (COMPILER_GCC OR COMPILER_CLANG)
|
||||
# to make numeric_limits<__int128> works with GCC
|
||||
set (_CXX_STANDARD "gnu++2a")
|
||||
else()
|
||||
set (_CXX_STANDARD "c++2a")
|
||||
endif()
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.12.4")
|
||||
# CMake < 3.12 doesn't support setting 20 as a C++ standard version.
|
||||
# We will add C++ standard controlling flag in CMAKE_CXX_FLAGS manually for now.
|
||||
|
||||
# cmake < 3.12 doesn't support 20. We'll set CMAKE_CXX_FLAGS for now
|
||||
# set (CMAKE_CXX_STANDARD 20)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=${_CXX_STANDARD}")
|
||||
if (COMPILER_GCC OR COMPILER_CLANG)
|
||||
# to make numeric_limits<__int128> works with GCC
|
||||
set (_CXX_STANDARD "gnu++2a")
|
||||
else ()
|
||||
set (_CXX_STANDARD "c++2a")
|
||||
endif ()
|
||||
|
||||
set (CMAKE_CXX_EXTENSIONS 0) # https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html#prop_tgt:CXX_EXTENSIONS
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=${_CXX_STANDARD}")
|
||||
else ()
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
set (CMAKE_CXX_EXTENSIONS ON) # Same as gnu++2a (ON) vs c++2a (OFF): https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif ()
|
||||
|
||||
set (CMAKE_C_STANDARD 11)
|
||||
set (CMAKE_C_EXTENSIONS ON)
|
||||
set (CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
if (COMPILER_GCC OR COMPILER_CLANG)
|
||||
# Enable C++14 sized global deallocation functions. It should be enabled by setting -std=c++14 but I'm not sure.
|
||||
@ -501,6 +509,7 @@ include (cmake/find/msgpack.cmake)
|
||||
include (cmake/find/cassandra.cmake)
|
||||
include (cmake/find/sentry.cmake)
|
||||
include (cmake/find/stats.cmake)
|
||||
include (cmake/find/datasketches.cmake)
|
||||
|
||||
set (USE_INTERNAL_CITYHASH_LIBRARY ON CACHE INTERNAL "")
|
||||
find_contrib_lib(cityhash)
|
||||
|
@ -47,6 +47,10 @@ endif()
|
||||
|
||||
target_include_directories(common PUBLIC .. ${CMAKE_CURRENT_BINARY_DIR}/..)
|
||||
|
||||
if (OS_DARWIN AND NOT MAKE_STATIC_LIBRARIES)
|
||||
target_link_libraries(common PUBLIC -Wl,-U,_inside_main)
|
||||
endif()
|
||||
|
||||
# Allow explicit fallback to readline
|
||||
if (NOT ENABLE_REPLXX AND ENABLE_READLINE)
|
||||
message (STATUS "Attempt to fallback to readline explicitly")
|
||||
|
@ -853,15 +853,43 @@ public:
|
||||
{
|
||||
if (hours == 1)
|
||||
return toStartOfHour(t);
|
||||
|
||||
/** We will round the hour number since the midnight.
|
||||
* It may split the day into non-equal intervals.
|
||||
* For example, if we will round to 11-hour interval,
|
||||
* the day will be split to the intervals 00:00:00..10:59:59, 11:00:00..21:59:59, 22:00:00..23:59:59.
|
||||
* In case of daylight saving time or other transitions,
|
||||
* the intervals can be shortened or prolonged to the amount of transition.
|
||||
*/
|
||||
|
||||
UInt64 seconds = hours * 3600;
|
||||
|
||||
t = roundDown(t, seconds);
|
||||
const LUTIndex index = findIndex(t);
|
||||
const Values & values = lut[index];
|
||||
|
||||
if (t >= 0 && offset_is_whole_number_of_hours_during_epoch)
|
||||
return t;
|
||||
time_t time = t - values.date;
|
||||
if (time >= values.time_at_offset_change())
|
||||
{
|
||||
/// Align to new hour numbers before rounding.
|
||||
time += values.amount_of_offset_change();
|
||||
time = time / seconds * seconds;
|
||||
|
||||
/// TODO check if it's correct.
|
||||
return toStartOfHour(t);
|
||||
/// Should subtract the shift back but only if rounded time is not before shift.
|
||||
if (time >= values.time_at_offset_change())
|
||||
{
|
||||
time -= values.amount_of_offset_change();
|
||||
|
||||
/// With cutoff at the time of the shift. Otherwise we may end up with something like 23:00 previous day.
|
||||
if (time < values.time_at_offset_change())
|
||||
time = values.time_at_offset_change();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
time = time / seconds * seconds;
|
||||
}
|
||||
|
||||
return values.date + time;
|
||||
}
|
||||
|
||||
inline time_t toStartOfMinuteInterval(time_t t, UInt64 minutes) const
|
||||
@ -869,6 +897,14 @@ public:
|
||||
if (minutes == 1)
|
||||
return toStartOfMinute(t);
|
||||
|
||||
/** In contrast to "toStartOfHourInterval" function above,
|
||||
* the minute intervals are not aligned to the midnight.
|
||||
* You will get unexpected results if for example, you round down to 60 minute interval
|
||||
* and there was a time shift to 30 minutes.
|
||||
*
|
||||
* But this is not specified in docs and can be changed in future.
|
||||
*/
|
||||
|
||||
UInt64 seconds = 60 * minutes;
|
||||
return roundDown(t, seconds);
|
||||
}
|
||||
@ -1069,11 +1105,11 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline LUTIndex addMonthsIndex(DateOrTime v, Int64 delta) const
|
||||
inline LUTIndex NO_SANITIZE_UNDEFINED addMonthsIndex(DateOrTime v, Int64 delta) const
|
||||
{
|
||||
const Values & values = lut[toLUTIndex(v)];
|
||||
|
||||
Int64 month = static_cast<Int64>(values.month) + delta;
|
||||
Int64 month = values.month + delta;
|
||||
|
||||
if (month > 0)
|
||||
{
|
||||
|
@ -25,6 +25,12 @@ namespace common
|
||||
return x - y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline auto NO_SANITIZE_UNDEFINED negateIgnoreOverflow(T x)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool addOverflow(T x, T y, T & res)
|
||||
{
|
||||
|
@ -1,45 +1,28 @@
|
||||
// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
|
||||
|
||||
#include <common/setTerminalEcho.h>
|
||||
#include <common/errnoToString.h>
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
|
||||
void setTerminalEcho(bool enable)
|
||||
{
|
||||
#ifdef WIN32
|
||||
auto handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD mode;
|
||||
if (!GetConsoleMode(handle, &mode))
|
||||
throw std::runtime_error(std::string("setTerminalEcho failed get: ") + std::to_string(GetLastError()));
|
||||
/// Obtain terminal attributes,
|
||||
/// toggle the ECHO flag
|
||||
/// and set them back.
|
||||
|
||||
if (!enable)
|
||||
mode &= ~ENABLE_ECHO_INPUT;
|
||||
else
|
||||
mode |= ENABLE_ECHO_INPUT;
|
||||
struct termios tty{};
|
||||
|
||||
if (!SetConsoleMode(handle, mode))
|
||||
throw std::runtime_error(std::string("setTerminalEcho failed set: ") + std::to_string(GetLastError()));
|
||||
#else
|
||||
struct termios tty;
|
||||
if (tcgetattr(STDIN_FILENO, &tty))
|
||||
if (0 != tcgetattr(STDIN_FILENO, &tty))
|
||||
throw std::runtime_error(std::string("setTerminalEcho failed get: ") + errnoToString(errno));
|
||||
if (!enable)
|
||||
tty.c_lflag &= ~ECHO;
|
||||
else
|
||||
tty.c_lflag |= ECHO;
|
||||
|
||||
auto ret = tcsetattr(STDIN_FILENO, TCSANOW, &tty);
|
||||
if (ret)
|
||||
if (enable)
|
||||
tty.c_lflag |= ECHO;
|
||||
else
|
||||
tty.c_lflag &= ~ECHO;
|
||||
|
||||
if (0 != tcsetattr(STDIN_FILENO, TCSANOW, &tty))
|
||||
throw std::runtime_error(std::string("setTerminalEcho failed set: ") + errnoToString(errno));
|
||||
#endif
|
||||
}
|
||||
|
@ -5,6 +5,11 @@ add_library (daemon
|
||||
)
|
||||
|
||||
target_include_directories (daemon PUBLIC ..)
|
||||
|
||||
if (OS_DARWIN AND NOT MAKE_STATIC_LIBRARIES)
|
||||
target_link_libraries (daemon PUBLIC -Wl,-undefined,dynamic_lookup)
|
||||
endif()
|
||||
|
||||
target_link_libraries (daemon PUBLIC loggers PRIVATE clickhouse_common_io clickhouse_common_config common ${EXECINFO_LIBRARIES})
|
||||
|
||||
if (USE_SENTRY)
|
||||
|
29
cmake/find/datasketches.cmake
Normal file
29
cmake/find/datasketches.cmake
Normal file
@ -0,0 +1,29 @@
|
||||
option (ENABLE_DATASKETCHES "Enable DataSketches" ${ENABLE_LIBRARIES})
|
||||
|
||||
if (ENABLE_DATASKETCHES)
|
||||
|
||||
option (USE_INTERNAL_DATASKETCHES_LIBRARY "Set to FALSE to use system DataSketches library instead of bundled" ${NOT_UNBUNDLED})
|
||||
|
||||
if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/datasketches-cpp/theta/CMakeLists.txt")
|
||||
if (USE_INTERNAL_DATASKETCHES_LIBRARY)
|
||||
message(WARNING "submodule contrib/datasketches-cpp is missing. to fix try run: \n git submodule update --init --recursive")
|
||||
endif()
|
||||
set(MISSING_INTERNAL_DATASKETCHES_LIBRARY 1)
|
||||
set(USE_INTERNAL_DATASKETCHES_LIBRARY 0)
|
||||
endif()
|
||||
|
||||
if (USE_INTERNAL_DATASKETCHES_LIBRARY)
|
||||
set(DATASKETCHES_LIBRARY theta)
|
||||
set(DATASKETCHES_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/datasketches-cpp/common/include" "${ClickHouse_SOURCE_DIR}/contrib/datasketches-cpp/theta/include")
|
||||
elseif (NOT MISSING_INTERNAL_DATASKETCHES_LIBRARY)
|
||||
find_library(DATASKETCHES_LIBRARY theta)
|
||||
find_path(DATASKETCHES_INCLUDE_DIR NAMES theta_sketch.hpp PATHS ${DATASKETCHES_INCLUDE_PATHS})
|
||||
endif()
|
||||
|
||||
if (DATASKETCHES_LIBRARY AND DATASKETCHES_INCLUDE_DIR)
|
||||
set(USE_DATASKETCHES 1)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
message (STATUS "Using datasketches=${USE_DATASKETCHES}: ${DATASKETCHES_INCLUDE_DIR} : ${DATASKETCHES_LIBRARY}")
|
@ -11,11 +11,6 @@ if (NOT MSVC)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
|
||||
endif ()
|
||||
|
||||
if (USE_DEBUG_HELPERS)
|
||||
set (INCLUDE_DEBUG_HELPERS "-I${ClickHouse_SOURCE_DIR}/base -include ${ClickHouse_SOURCE_DIR}/src/Core/iostream_debug_helpers.h")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${INCLUDE_DEBUG_HELPERS}")
|
||||
endif ()
|
||||
|
||||
# Add some warnings that are not available even with -Wall -Wextra -Wpedantic.
|
||||
# Intended for exploration of new compiler warnings that may be found useful.
|
||||
# Applies to clang only
|
||||
|
25
contrib/CMakeLists.txt
vendored
25
contrib/CMakeLists.txt
vendored
@ -215,15 +215,17 @@ if (USE_EMBEDDED_COMPILER AND USE_INTERNAL_LLVM_LIBRARY)
|
||||
set (LLVM_ENABLE_RTTI 1 CACHE INTERNAL "")
|
||||
set (LLVM_ENABLE_PIC 0 CACHE INTERNAL "")
|
||||
set (LLVM_TARGETS_TO_BUILD "X86;AArch64" CACHE STRING "")
|
||||
# Yes it is set globally, but this is not enough, since llvm will add -std=c++11 after default
|
||||
# And c++2a cannot be used, due to ambiguous operator !=
|
||||
if (COMPILER_GCC OR COMPILER_CLANG)
|
||||
set (_CXX_STANDARD "gnu++17")
|
||||
else()
|
||||
set (_CXX_STANDARD "c++17")
|
||||
endif()
|
||||
set (LLVM_CXX_STD ${_CXX_STANDARD} CACHE STRING "" FORCE)
|
||||
|
||||
# Need to use C++17 since the compilation is not possible with C++20 currently, due to ambiguous operator != etc.
|
||||
# LLVM project will set its default value for the -std=... but our global setting from CMake will override it.
|
||||
set (CMAKE_CXX_STANDARD_bak ${CMAKE_CXX_STANDARD})
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_subdirectory (llvm/llvm)
|
||||
|
||||
set (CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD_bak})
|
||||
unset (CMAKE_CXX_STANDARD_bak)
|
||||
|
||||
target_include_directories(LLVMSupport SYSTEM BEFORE PRIVATE ${ZLIB_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
@ -280,7 +282,14 @@ if (USE_AMQPCPP)
|
||||
add_subdirectory (amqpcpp-cmake)
|
||||
endif()
|
||||
if (USE_CASSANDRA)
|
||||
# Need to use C++17 since the compilation is not possible with C++20 currently.
|
||||
set (CMAKE_CXX_STANDARD_bak ${CMAKE_CXX_STANDARD})
|
||||
set (CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_subdirectory (cassandra)
|
||||
|
||||
set (CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD_bak})
|
||||
unset (CMAKE_CXX_STANDARD_bak)
|
||||
endif()
|
||||
|
||||
# Should go before:
|
||||
|
2
contrib/NuRaft
vendored
2
contrib/NuRaft
vendored
@ -1 +1 @@
|
||||
Subproject commit 3d3683e77753cfe015a05fae95ddf418e19f59e1
|
||||
Subproject commit 70468326ad5d72e9497944838484c591dae054ea
|
2
contrib/arrow
vendored
2
contrib/arrow
vendored
@ -1 +1 @@
|
||||
Subproject commit 744bdfe188f018e5e05f5deebd4e9ee0a7706cf4
|
||||
Subproject commit 616b3dc76a0c8450b4027ded8a78e9619d7c845f
|
1
contrib/datasketches-cpp
vendored
Submodule
1
contrib/datasketches-cpp
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit f915d35b2de676683493c86c585141a1e1c83334
|
2
contrib/grpc
vendored
2
contrib/grpc
vendored
@ -1 +1 @@
|
||||
Subproject commit 7436366ceb341ba5c00ea29f1645e02a2b70bf93
|
||||
Subproject commit 8d558f03fe370240081424fafa76cdc9301ea14b
|
File diff suppressed because it is too large
Load Diff
2
contrib/replxx
vendored
2
contrib/replxx
vendored
@ -1 +1 @@
|
||||
Subproject commit cdb6e3f2ce4464225daf9c8beeae7db98d590bdc
|
||||
Subproject commit 2b24f14594d7606792b92544bb112a6322ba34d7
|
2
contrib/simdjson
vendored
2
contrib/simdjson
vendored
@ -1 +1 @@
|
||||
Subproject commit 3190d66a49059092a1753dc35595923debfc1698
|
||||
Subproject commit 95b4870e20be5f97d9dcf63b23b1c6f520c366c1
|
@ -18,6 +18,7 @@ RUN apt-get update \
|
||||
clickhouse-client=$version \
|
||||
clickhouse-common-static=$version \
|
||||
locales \
|
||||
tzdata \
|
||||
&& rm -rf /var/lib/apt/lists/* /var/cache/debconf \
|
||||
&& apt-get clean
|
||||
|
||||
|
@ -14,12 +14,8 @@ RUN apt-get update \
|
||||
lsb-release \
|
||||
wget \
|
||||
--yes --no-install-recommends --verbose-versions \
|
||||
&& cat /etc/resolv.conf \
|
||||
&& echo "nameserver 1.1.1.1" >> /etc/resolv.conf \
|
||||
&& nslookup -debug apt.llvm.org \
|
||||
&& ping -c1 apt.llvm.org \
|
||||
&& wget -nv --retry-connrefused --tries=10 -O /tmp/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key \
|
||||
&& export LLVM_PUBKEY_HASH="bda960a8da687a275a2078d43c111d66b1c6a893a3275271beedf266c1ff4a0cdecb429c7a5cccf9f486ea7aa43fd27f" \
|
||||
&& wget -nv -O /tmp/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key \
|
||||
&& echo "${LLVM_PUBKEY_HASH} /tmp/llvm-snapshot.gpg.key" | sha384sum -c \
|
||||
&& apt-key add /tmp/llvm-snapshot.gpg.key \
|
||||
&& export CODENAME="$(lsb_release --codename --short | tr 'A-Z' 'a-z')" \
|
||||
@ -36,10 +32,7 @@ RUN apt-get update \
|
||||
software-properties-common \
|
||||
--yes --no-install-recommends
|
||||
|
||||
RUN cat /etc/resolv.conf \
|
||||
&& echo "nameserver 1.1.1.1" >> /etc/resolv.conf \
|
||||
&& nslookup -debug apt.llvm.org \
|
||||
&& apt-get update \
|
||||
RUN apt-get update \
|
||||
&& apt-get install \
|
||||
bash \
|
||||
cmake \
|
||||
|
@ -4,6 +4,21 @@ ARG repository="deb https://repo.clickhouse.tech/deb/stable/ main/"
|
||||
ARG version=21.4.1.*
|
||||
ARG gosu_ver=1.10
|
||||
|
||||
# set non-empty deb_location_url url to create a docker image
|
||||
# from debs created by CI build, for example:
|
||||
# docker build . --network host --build-arg version="21.4.1.6282" --build-arg deb_location_url="https://clickhouse-builds.s3.yandex.net/21852/069cfbff388b3d478d1a16dc7060b48073f5d522/clickhouse_build_check/clang-11_relwithdebuginfo_none_bundled_unsplitted_disable_False_deb/" -t filimonovq/clickhouse-server:pr21852
|
||||
ARG deb_location_url=""
|
||||
|
||||
# set non-empty single_binary_location_url to create docker image
|
||||
# from a single binary url (useful for non-standard builds - with sanitizers, for arm64).
|
||||
# for example (run on aarch64 server):
|
||||
# docker build . --network host --build-arg single_binary_location_url="https://builds.clickhouse.tech/master/aarch64/clickhouse" -t altinity/clickhouse-server:master-testing-arm
|
||||
# note: clickhouse-odbc-bridge is not supported there.
|
||||
ARG single_binary_location_url=""
|
||||
|
||||
# see https://github.com/moby/moby/issues/4032#issuecomment-192327844
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# user/group precreated explicitly with fixed uid/gid on purpose.
|
||||
# It is especially important for rootless containers: in that case entrypoint
|
||||
# can't do chown and owners of mounted volumes should be configured externally.
|
||||
@ -19,19 +34,37 @@ RUN groupadd -r clickhouse --gid=101 \
|
||||
ca-certificates \
|
||||
dirmngr \
|
||||
gnupg \
|
||||
locales \
|
||||
wget \
|
||||
tzdata \
|
||||
&& mkdir -p /etc/apt/sources.list.d \
|
||||
&& apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4 \
|
||||
&& echo $repository > /etc/apt/sources.list.d/clickhouse.list \
|
||||
&& apt-get update \
|
||||
&& env DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get --yes -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade \
|
||||
&& env DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get install --allow-unauthenticated --yes --no-install-recommends \
|
||||
clickhouse-common-static=$version \
|
||||
clickhouse-client=$version \
|
||||
clickhouse-server=$version \
|
||||
locales \
|
||||
wget \
|
||||
&& if [ -n "$deb_location_url" ]; then \
|
||||
echo "installing from custom url with deb packages: $deb_location_url" \
|
||||
rm -rf /tmp/clickhouse_debs \
|
||||
&& mkdir -p /tmp/clickhouse_debs \
|
||||
&& wget --progress=bar:force:noscroll "${deb_location_url}/clickhouse-common-static_${version}_amd64.deb" -P /tmp/clickhouse_debs \
|
||||
&& wget --progress=bar:force:noscroll "${deb_location_url}/clickhouse-client_${version}_all.deb" -P /tmp/clickhouse_debs \
|
||||
&& wget --progress=bar:force:noscroll "${deb_location_url}/clickhouse-server_${version}_all.deb" -P /tmp/clickhouse_debs \
|
||||
&& dpkg -i /tmp/clickhouse_debs/*.deb ; \
|
||||
elif [ -n "$single_binary_location_url" ]; then \
|
||||
echo "installing from single binary url: $single_binary_location_url" \
|
||||
&& rm -rf /tmp/clickhouse_binary \
|
||||
&& mkdir -p /tmp/clickhouse_binary \
|
||||
&& wget --progress=bar:force:noscroll "$single_binary_location_url" -O /tmp/clickhouse_binary/clickhouse \
|
||||
&& chmod +x /tmp/clickhouse_binary/clickhouse \
|
||||
&& /tmp/clickhouse_binary/clickhouse install --user "clickhouse" --group "clickhouse" ; \
|
||||
else \
|
||||
echo "installing from repository: $repository" \
|
||||
&& apt-get update \
|
||||
&& apt-get --yes -o "Dpkg::Options::=--force-confdef" -o "Dpkg::Options::=--force-confold" upgrade \
|
||||
&& apt-get install --allow-unauthenticated --yes --no-install-recommends \
|
||||
clickhouse-common-static=$version \
|
||||
clickhouse-client=$version \
|
||||
clickhouse-server=$version ; \
|
||||
fi \
|
||||
&& clickhouse-local -q 'SELECT * FROM system.build_options' \
|
||||
&& rm -rf \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/cache/debconf \
|
||||
|
@ -21,7 +21,9 @@ RUN addgroup -S -g 101 clickhouse \
|
||||
&& chown clickhouse:clickhouse /var/lib/clickhouse \
|
||||
&& chown root:clickhouse /var/log/clickhouse-server \
|
||||
&& chmod +x /entrypoint.sh \
|
||||
&& apk add --no-cache su-exec bash \
|
||||
&& apk add --no-cache su-exec bash tzdata \
|
||||
&& cp /usr/share/zoneinfo/UTC /etc/localtime \
|
||||
&& echo "UTC" > /etc/timezone \
|
||||
&& chmod ugo+Xrw -R /var/lib/clickhouse /var/log/clickhouse-server /etc/clickhouse-server /etc/clickhouse-client
|
||||
|
||||
# we need to allow "others" access to clickhouse folder, because docker container
|
||||
|
@ -38,17 +38,16 @@ if ! $gosu test -f "$CLICKHOUSE_CONFIG" -a -r "$CLICKHOUSE_CONFIG"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# port is needed to check if clickhouse-server is ready for connections
|
||||
HTTP_PORT="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=http_port)"
|
||||
|
||||
# get CH directories locations
|
||||
DATA_DIR="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=path || true)"
|
||||
TMP_DIR="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=tmp_path || true)"
|
||||
USER_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=user_files_path || true)"
|
||||
LOG_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=logger.log || true)"
|
||||
LOG_DIR="$(dirname "$LOG_PATH" || true)"
|
||||
LOG_DIR=""
|
||||
if [ -n "$LOG_PATH" ]; then LOG_DIR="$(dirname "$LOG_PATH")"; fi
|
||||
ERROR_LOG_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=logger.errorlog || true)"
|
||||
ERROR_LOG_DIR="$(dirname "$ERROR_LOG_PATH" || true)"
|
||||
ERROR_LOG_DIR=""
|
||||
if [ -n "$ERROR_LOG_PATH" ]; then ERROR_LOG_DIR="$(dirname "$ERROR_LOG_PATH")"; fi
|
||||
FORMAT_SCHEMA_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=format_schema_path || true)"
|
||||
|
||||
CLICKHOUSE_USER="${CLICKHOUSE_USER:-default}"
|
||||
@ -106,6 +105,9 @@ EOT
|
||||
fi
|
||||
|
||||
if [ -n "$(ls /docker-entrypoint-initdb.d/)" ] || [ -n "$CLICKHOUSE_DB" ]; then
|
||||
# port is needed to check if clickhouse-server is ready for connections
|
||||
HTTP_PORT="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=http_port)"
|
||||
|
||||
# Listen only on localhost until the initialization is done
|
||||
$gosu /usr/bin/clickhouse-server --config-file="$CLICKHOUSE_CONFIG" -- --listen_host=127.0.0.1 &
|
||||
pid="$!"
|
||||
|
@ -4,9 +4,8 @@ FROM ubuntu:20.04
|
||||
ENV DEBIAN_FRONTEND=noninteractive LLVM_VERSION=11
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install apt-utils ca-certificates lsb-release wget gnupg apt-transport-https \
|
||||
&& apt-get install ca-certificates lsb-release wget gnupg apt-transport-https \
|
||||
--yes --no-install-recommends --verbose-versions \
|
||||
&& echo "nameserver 1.1.1.1" >> /etc/resolv.conf \
|
||||
&& export LLVM_PUBKEY_HASH="bda960a8da687a275a2078d43c111d66b1c6a893a3275271beedf266c1ff4a0cdecb429c7a5cccf9f486ea7aa43fd27f" \
|
||||
&& wget -nv -O /tmp/llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key \
|
||||
&& echo "${LLVM_PUBKEY_HASH} /tmp/llvm-snapshot.gpg.key" | sha384sum -c \
|
||||
@ -32,8 +31,7 @@ RUN curl -O https://clickhouse-builds.s3.yandex.net/utils/1/dpkg-deb \
|
||||
&& chmod +x dpkg-deb \
|
||||
&& cp dpkg-deb /usr/bin
|
||||
|
||||
RUN echo "nameserver 1.1.1.1" >> /etc/resolv.conf \
|
||||
&& apt-get update \
|
||||
RUN apt-get update \
|
||||
&& apt-get install \
|
||||
clang-${LLVM_VERSION} \
|
||||
debhelper \
|
||||
|
@ -70,7 +70,7 @@ function start_server
|
||||
--path "$FASTTEST_DATA"
|
||||
--user_files_path "$FASTTEST_DATA/user_files"
|
||||
--top_level_domains_path "$FASTTEST_DATA/top_level_domains"
|
||||
--test_keeper_server.log_storage_path "$FASTTEST_DATA/coordination"
|
||||
--keeper_server.log_storage_path "$FASTTEST_DATA/coordination"
|
||||
)
|
||||
clickhouse-server "${opts[@]}" &>> "$FASTTEST_OUTPUT/server.log" &
|
||||
server_pid=$!
|
||||
@ -292,6 +292,7 @@ function run_tests
|
||||
01318_decrypt # Depends on OpenSSL
|
||||
01663_aes_msan # Depends on OpenSSL
|
||||
01667_aes_args_check # Depends on OpenSSL
|
||||
01776_decrypt_aead_size_check # Depends on OpenSSL
|
||||
01281_unsucceeded_insert_select_queries_counter
|
||||
01292_create_user
|
||||
01294_lazy_database_concurrent
|
||||
|
@ -3,7 +3,7 @@
|
||||
<mysql_port remove="remove"/>
|
||||
<interserver_http_port remove="remove"/>
|
||||
<tcp_with_proxy_port remove="remove"/>
|
||||
<test_keeper_server remove="remove"/>
|
||||
<keeper_server remove="remove"/>
|
||||
<listen_host>::</listen_host>
|
||||
|
||||
<logger>
|
||||
|
@ -266,14 +266,13 @@ for query_index in queries_to_run:
|
||||
|
||||
try:
|
||||
# Will also detect too long queries during warmup stage
|
||||
res = c.execute(q, query_id = prewarm_id, settings = {'max_execution_time': 10})
|
||||
res = c.execute(q, query_id = prewarm_id, settings = {'max_execution_time': args.max_query_seconds})
|
||||
except clickhouse_driver.errors.Error as e:
|
||||
# Add query id to the exception to make debugging easier.
|
||||
e.args = (prewarm_id, *e.args)
|
||||
e.message = prewarm_id + ': ' + e.message
|
||||
raise
|
||||
|
||||
|
||||
print(f'prewarm\t{query_index}\t{prewarm_id}\t{conn_index}\t{c.last_query.elapsed}')
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
@ -320,7 +319,7 @@ for query_index in queries_to_run:
|
||||
|
||||
for conn_index, c in enumerate(this_query_connections):
|
||||
try:
|
||||
res = c.execute(q, query_id = run_id)
|
||||
res = c.execute(q, query_id = run_id, settings = {'max_execution_time': args.max_query_seconds})
|
||||
except clickhouse_driver.errors.Error as e:
|
||||
# Add query id to the exception to make debugging easier.
|
||||
e.args = (run_id, *e.args)
|
||||
|
@ -2,7 +2,6 @@
|
||||
FROM ubuntu:20.04
|
||||
|
||||
RUN apt-get update --yes && env DEBIAN_FRONTEND=noninteractive apt-get install wget unzip git openjdk-14-jdk maven python3 --yes --no-install-recommends
|
||||
|
||||
RUN wget https://github.com/sqlancer/sqlancer/archive/master.zip -O /sqlancer.zip
|
||||
RUN mkdir /sqlancer && \
|
||||
cd /sqlancer && \
|
||||
|
@ -13,6 +13,25 @@ dpkg -i package_folder/clickhouse-test_*.deb
|
||||
|
||||
function start()
|
||||
{
|
||||
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then
|
||||
# NOTE We run "clickhouse server" instead of "clickhouse-server"
|
||||
# to make "pidof clickhouse-server" return single pid of the main instance.
|
||||
# We wil run main instance using "service clickhouse-server start"
|
||||
sudo -E -u clickhouse /usr/bin/clickhouse server --config /etc/clickhouse-server1/config.xml --daemon \
|
||||
-- --path /var/lib/clickhouse1/ --logger.stderr /var/log/clickhouse-server/stderr1.log \
|
||||
--logger.log /var/log/clickhouse-server/clickhouse-server1.log --logger.errorlog /var/log/clickhouse-server/clickhouse-server1.err.log \
|
||||
--tcp_port 19000 --tcp_port_secure 19440 --http_port 18123 --https_port 18443 --interserver_http_port 19009 --tcp_with_proxy_port 19010 \
|
||||
--mysql_port 19004 \
|
||||
--keeper_server.tcp_port 19181 --keeper_server.server_id 2
|
||||
|
||||
sudo -E -u clickhouse /usr/bin/clickhouse server --config /etc/clickhouse-server2/config.xml --daemon \
|
||||
-- --path /var/lib/clickhouse2/ --logger.stderr /var/log/clickhouse-server/stderr2.log \
|
||||
--logger.log /var/log/clickhouse-server/clickhouse-server2.log --logger.errorlog /var/log/clickhouse-server/clickhouse-server2.err.log \
|
||||
--tcp_port 29000 --tcp_port_secure 29440 --http_port 28123 --https_port 28443 --interserver_http_port 29009 --tcp_with_proxy_port 29010 \
|
||||
--mysql_port 29004 \
|
||||
--keeper_server.tcp_port 29181 --keeper_server.server_id 3
|
||||
fi
|
||||
|
||||
counter=0
|
||||
until clickhouse-client --query "SELECT 1"
|
||||
do
|
||||
@ -35,9 +54,8 @@ start
|
||||
/s3downloader --dataset-names $DATASETS
|
||||
chmod 777 -R /var/lib/clickhouse
|
||||
clickhouse-client --query "SHOW DATABASES"
|
||||
clickhouse-client --query "ATTACH DATABASE datasets ENGINE = Ordinary"
|
||||
clickhouse-client --query "CREATE DATABASE test"
|
||||
|
||||
clickhouse-client --query "ATTACH DATABASE datasets ENGINE = Ordinary"
|
||||
service clickhouse-server restart
|
||||
|
||||
# Wait for server to start accepting connections
|
||||
@ -47,24 +65,50 @@ for _ in {1..120}; do
|
||||
done
|
||||
|
||||
clickhouse-client --query "SHOW TABLES FROM datasets"
|
||||
clickhouse-client --query "SHOW TABLES FROM test"
|
||||
clickhouse-client --query "RENAME TABLE datasets.hits_v1 TO test.hits"
|
||||
clickhouse-client --query "RENAME TABLE datasets.visits_v1 TO test.visits"
|
||||
clickhouse-client --query "SHOW TABLES FROM test"
|
||||
|
||||
if grep -q -- "--use-skip-list" /usr/bin/clickhouse-test ; then
|
||||
SKIP_LIST_OPT="--use-skip-list"
|
||||
fi
|
||||
|
||||
# We can have several additional options so we path them as array because it's
|
||||
# more idiologically correct.
|
||||
read -ra ADDITIONAL_OPTIONS <<< "${ADDITIONAL_OPTIONS:-}"
|
||||
|
||||
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then
|
||||
ADDITIONAL_OPTIONS+=('--replicated-database')
|
||||
clickhouse-client --query "CREATE DATABASE test ON CLUSTER 'test_cluster_database_replicated'
|
||||
ENGINE=Replicated('/test/clickhouse/db/test', '{shard}', '{replica}')"
|
||||
|
||||
clickhouse-client --query "CREATE TABLE test.hits AS datasets.hits_v1"
|
||||
clickhouse-client --query "CREATE TABLE test.visits AS datasets.visits_v1"
|
||||
|
||||
clickhouse-client --query "INSERT INTO test.hits SELECT * FROM datasets.hits_v1"
|
||||
clickhouse-client --query "INSERT INTO test.visits SELECT * FROM datasets.visits_v1"
|
||||
|
||||
clickhouse-client --query "DROP TABLE datasets.hits_v1"
|
||||
clickhouse-client --query "DROP TABLE datasets.visits_v1"
|
||||
|
||||
MAX_RUN_TIME=$((MAX_RUN_TIME < 9000 ? MAX_RUN_TIME : 9000)) # min(MAX_RUN_TIME, 2.5 hours)
|
||||
MAX_RUN_TIME=$((MAX_RUN_TIME != 0 ? MAX_RUN_TIME : 9000)) # set to 2.5 hours if 0 (unlimited)
|
||||
else
|
||||
clickhouse-client --query "CREATE DATABASE test"
|
||||
clickhouse-client --query "SHOW TABLES FROM test"
|
||||
clickhouse-client --query "RENAME TABLE datasets.hits_v1 TO test.hits"
|
||||
clickhouse-client --query "RENAME TABLE datasets.visits_v1 TO test.visits"
|
||||
fi
|
||||
|
||||
clickhouse-test --testname --shard --zookeeper --no-stateless --hung-check --print-time "$SKIP_LIST_OPT" "${ADDITIONAL_OPTIONS[@]}" "$SKIP_TESTS_OPTION" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee test_output/test_result.txt
|
||||
clickhouse-client --query "SHOW TABLES FROM test"
|
||||
clickhouse-client --query "SELECT count() FROM test.hits"
|
||||
clickhouse-client --query "SELECT count() FROM test.visits"
|
||||
|
||||
function run_tests()
|
||||
{
|
||||
set -x
|
||||
# We can have several additional options so we path them as array because it's
|
||||
# more idiologically correct.
|
||||
read -ra ADDITIONAL_OPTIONS <<< "${ADDITIONAL_OPTIONS:-}"
|
||||
|
||||
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then
|
||||
ADDITIONAL_OPTIONS+=('--replicated-database')
|
||||
fi
|
||||
|
||||
clickhouse-test --testname --shard --zookeeper --no-stateless --hung-check --use-skip-list --print-time "${ADDITIONAL_OPTIONS[@]}" \
|
||||
"$SKIP_TESTS_OPTION" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee test_output/test_result.txt
|
||||
}
|
||||
|
||||
export -f run_tests
|
||||
timeout "$MAX_RUN_TIME" bash -c run_tests ||:
|
||||
|
||||
./process_functional_tests_result.py || echo -e "failure\tCannot parse results" > /test_output/check_status.tsv
|
||||
|
||||
@ -73,3 +117,9 @@ mv /var/log/clickhouse-server/stderr.log /test_output/ ||:
|
||||
if [[ -n "$WITH_COVERAGE" ]] && [[ "$WITH_COVERAGE" -eq 1 ]]; then
|
||||
tar -chf /test_output/clickhouse_coverage.tar.gz /profraw ||:
|
||||
fi
|
||||
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then
|
||||
pigz < /var/log/clickhouse-server/clickhouse-server1.log > /test_output/clickhouse-server1.log.gz ||:
|
||||
pigz < /var/log/clickhouse-server/clickhouse-server2.log > /test_output/clickhouse-server2.log.gz ||:
|
||||
mv /var/log/clickhouse-server/stderr1.log /test_output/ ||:
|
||||
mv /var/log/clickhouse-server/stderr2.log /test_output/ ||:
|
||||
fi
|
||||
|
@ -12,6 +12,8 @@ UNKNOWN_SIGN = "[ UNKNOWN "
|
||||
SKIPPED_SIGN = "[ SKIPPED "
|
||||
HUNG_SIGN = "Found hung queries in processlist"
|
||||
|
||||
NO_TASK_TIMEOUT_SIGN = "All tests have finished"
|
||||
|
||||
def process_test_log(log_path):
|
||||
total = 0
|
||||
skipped = 0
|
||||
@ -19,10 +21,13 @@ def process_test_log(log_path):
|
||||
failed = 0
|
||||
success = 0
|
||||
hung = False
|
||||
task_timeout = True
|
||||
test_results = []
|
||||
with open(log_path, 'r') as test_file:
|
||||
for line in test_file:
|
||||
line = line.strip()
|
||||
if NO_TASK_TIMEOUT_SIGN in line:
|
||||
task_timeout = False
|
||||
if HUNG_SIGN in line:
|
||||
hung = True
|
||||
if any(sign in line for sign in (OK_SIGN, FAIL_SING, UNKNOWN_SIGN, SKIPPED_SIGN)):
|
||||
@ -52,7 +57,7 @@ def process_test_log(log_path):
|
||||
else:
|
||||
success += int(OK_SIGN in line)
|
||||
test_results.append((test_name, "OK", test_time))
|
||||
return total, skipped, unknown, failed, success, hung, test_results
|
||||
return total, skipped, unknown, failed, success, hung, task_timeout, test_results
|
||||
|
||||
def process_result(result_path):
|
||||
test_results = []
|
||||
@ -68,7 +73,7 @@ def process_result(result_path):
|
||||
state = "error"
|
||||
|
||||
if result_path and os.path.exists(result_path):
|
||||
total, skipped, unknown, failed, success, hung, test_results = process_test_log(result_path)
|
||||
total, skipped, unknown, failed, success, hung, task_timeout, test_results = process_test_log(result_path)
|
||||
is_flacky_check = 1 < int(os.environ.get('NUM_TRIES', 1))
|
||||
# If no tests were run (success == 0) it indicates an error (e.g. server did not start or crashed immediately)
|
||||
# But it's Ok for "flaky checks" - they can contain just one test for check which is marked as skipped.
|
||||
@ -78,6 +83,9 @@ def process_result(result_path):
|
||||
if hung:
|
||||
description = "Some queries hung, "
|
||||
state = "failure"
|
||||
elif task_timeout:
|
||||
description = "Timeout, "
|
||||
state = "failure"
|
||||
else:
|
||||
description = ""
|
||||
|
||||
|
@ -34,23 +34,44 @@ if [ "$NUM_TRIES" -gt "1" ]; then
|
||||
|
||||
# simpliest way to forward env variables to server
|
||||
sudo -E -u clickhouse /usr/bin/clickhouse-server --config /etc/clickhouse-server/config.xml --daemon
|
||||
sleep 5
|
||||
else
|
||||
service clickhouse-server start && sleep 5
|
||||
service clickhouse-server start
|
||||
fi
|
||||
|
||||
if grep -q -- "--use-skip-list" /usr/bin/clickhouse-test; then
|
||||
SKIP_LIST_OPT="--use-skip-list"
|
||||
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then
|
||||
|
||||
sudo -E -u clickhouse /usr/bin/clickhouse server --config /etc/clickhouse-server1/config.xml --daemon \
|
||||
-- --path /var/lib/clickhouse1/ --logger.stderr /var/log/clickhouse-server/stderr1.log \
|
||||
--logger.log /var/log/clickhouse-server/clickhouse-server1.log --logger.errorlog /var/log/clickhouse-server/clickhouse-server1.err.log \
|
||||
--tcp_port 19000 --tcp_port_secure 19440 --http_port 18123 --https_port 18443 --interserver_http_port 19009 --tcp_with_proxy_port 19010 \
|
||||
--mysql_port 19004 \
|
||||
--keeper_server.tcp_port 19181 --keeper_server.server_id 2 \
|
||||
--macros.replica r2 # It doesn't work :(
|
||||
|
||||
sudo -E -u clickhouse /usr/bin/clickhouse server --config /etc/clickhouse-server2/config.xml --daemon \
|
||||
-- --path /var/lib/clickhouse2/ --logger.stderr /var/log/clickhouse-server/stderr2.log \
|
||||
--logger.log /var/log/clickhouse-server/clickhouse-server2.log --logger.errorlog /var/log/clickhouse-server/clickhouse-server2.err.log \
|
||||
--tcp_port 29000 --tcp_port_secure 29440 --http_port 28123 --https_port 28443 --interserver_http_port 29009 --tcp_with_proxy_port 29010 \
|
||||
--mysql_port 29004 \
|
||||
--keeper_server.tcp_port 29181 --keeper_server.server_id 3 \
|
||||
--macros.shard s2 # It doesn't work :(
|
||||
|
||||
MAX_RUN_TIME=$((MAX_RUN_TIME < 9000 ? MAX_RUN_TIME : 9000)) # min(MAX_RUN_TIME, 2.5 hours)
|
||||
MAX_RUN_TIME=$((MAX_RUN_TIME != 0 ? MAX_RUN_TIME : 9000)) # set to 2.5 hours if 0 (unlimited)
|
||||
fi
|
||||
|
||||
sleep 5
|
||||
|
||||
function run_tests()
|
||||
{
|
||||
set -x
|
||||
# We can have several additional options so we path them as array because it's
|
||||
# more idiologically correct.
|
||||
read -ra ADDITIONAL_OPTIONS <<< "${ADDITIONAL_OPTIONS:-}"
|
||||
|
||||
# Skip these tests, because they fail when we rerun them multiple times
|
||||
if [ "$NUM_TRIES" -gt "1" ]; then
|
||||
ADDITIONAL_OPTIONS+=('--order=random')
|
||||
ADDITIONAL_OPTIONS+=('--skip')
|
||||
ADDITIONAL_OPTIONS+=('00000_no_tests_to_skip')
|
||||
ADDITIONAL_OPTIONS+=('--jobs')
|
||||
@ -62,8 +83,7 @@ function run_tests()
|
||||
fi
|
||||
|
||||
clickhouse-test --testname --shard --zookeeper --hung-check --print-time \
|
||||
--test-runs "$NUM_TRIES" \
|
||||
"$SKIP_LIST_OPT" "${ADDITIONAL_OPTIONS[@]}" 2>&1 \
|
||||
--use-skip-list --test-runs "$NUM_TRIES" "${ADDITIONAL_OPTIONS[@]}" 2>&1 \
|
||||
| ts '%Y-%m-%d %H:%M:%S' \
|
||||
| tee -a test_output/test_result.txt
|
||||
}
|
||||
@ -74,10 +94,23 @@ timeout "$MAX_RUN_TIME" bash -c run_tests ||:
|
||||
|
||||
./process_functional_tests_result.py || echo -e "failure\tCannot parse results" > /test_output/check_status.tsv
|
||||
|
||||
pigz < /var/log/clickhouse-server/clickhouse-server.log > /test_output/clickhouse-server.log.gz ||:
|
||||
clickhouse-client -q "system flush logs" ||:
|
||||
|
||||
pigz < /var/log/clickhouse-server/clickhouse-server.log > /test_output/clickhouse-server.log.gz &
|
||||
clickhouse-client -q "select * from system.query_log format TSVWithNamesAndTypes" | pigz > /test_output/query-log.tsv.gz &
|
||||
clickhouse-client -q "select * from system.query_thread_log format TSVWithNamesAndTypes" | pigz > /test_output/query-thread-log.tsv.gz &
|
||||
wait ||:
|
||||
|
||||
mv /var/log/clickhouse-server/stderr.log /test_output/ ||:
|
||||
if [[ -n "$WITH_COVERAGE" ]] && [[ "$WITH_COVERAGE" -eq 1 ]]; then
|
||||
tar -chf /test_output/clickhouse_coverage.tar.gz /profraw ||:
|
||||
fi
|
||||
tar -chf /test_output/text_log_dump.tar /var/lib/clickhouse/data/system/text_log ||:
|
||||
tar -chf /test_output/query_log_dump.tar /var/lib/clickhouse/data/system/query_log ||:
|
||||
|
||||
if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then
|
||||
pigz < /var/log/clickhouse-server/clickhouse-server1.log > /test_output/clickhouse-server1.log.gz ||:
|
||||
pigz < /var/log/clickhouse-server/clickhouse-server2.log > /test_output/clickhouse-server2.log.gz ||:
|
||||
mv /var/log/clickhouse-server/stderr1.log /test_output/ ||:
|
||||
mv /var/log/clickhouse-server/stderr2.log /test_output/ ||:
|
||||
fi
|
||||
|
@ -69,7 +69,7 @@ MySQL DDL queries are converted into the corresponding ClickHouse DDL queries ([
|
||||
|
||||
- MySQL `INSERT` query is converted into `INSERT` with `_sign=1`.
|
||||
|
||||
- MySQl `DELETE` query is converted into `INSERT` with `_sign=-1`.
|
||||
- MySQL `DELETE` query is converted into `INSERT` with `_sign=-1`.
|
||||
|
||||
- MySQL `UPDATE` query is converted into `INSERT` with `_sign=-1` and `INSERT` with `_sign=1`.
|
||||
|
||||
|
@ -3,7 +3,7 @@ toc_priority: 8
|
||||
toc_title: PostgreSQL
|
||||
---
|
||||
|
||||
# PosgtreSQL {#postgresql}
|
||||
# PostgreSQL {#postgresql}
|
||||
|
||||
The PostgreSQL engine allows you to perform `SELECT` queries on data that is stored on a remote PostgreSQL server.
|
||||
|
||||
|
@ -19,7 +19,7 @@ $ echo '{"foo":"bar"}' | curl 'http://localhost:8123/?query=INSERT%20INTO%20test
|
||||
Using [CLI interface](../../interfaces/cli.md):
|
||||
|
||||
``` bash
|
||||
$ echo '{"foo":"bar"}' | clickhouse-client ---query="INSERT INTO test FORMAT JSONEachRow"
|
||||
$ echo '{"foo":"bar"}' | clickhouse-client --query="INSERT INTO test FORMAT JSONEachRow"
|
||||
```
|
||||
|
||||
Instead of inserting data manually, you might consider to use one of [client libraries](../../interfaces/index.md) instead.
|
||||
|
@ -50,7 +50,7 @@ The supported formats are:
|
||||
| [Parquet](#data-format-parquet) | ✔ | ✔ |
|
||||
| [Arrow](#data-format-arrow) | ✔ | ✔ |
|
||||
| [ArrowStream](#data-format-arrow-stream) | ✔ | ✔ |
|
||||
| [ORC](#data-format-orc) | ✔ | ✗ |
|
||||
| [ORC](#data-format-orc) | ✔ | ✔ |
|
||||
| [RowBinary](#rowbinary) | ✔ | ✔ |
|
||||
| [RowBinaryWithNamesAndTypes](#rowbinarywithnamesandtypes) | ✔ | ✔ |
|
||||
| [Native](#native) | ✔ | ✔ |
|
||||
@ -1284,32 +1284,33 @@ To exchange data with Hadoop, you can use [HDFS table engine](../engines/table-e
|
||||
|
||||
## ORC {#data-format-orc}
|
||||
|
||||
[Apache ORC](https://orc.apache.org/) is a columnar storage format widespread in the Hadoop ecosystem. You can only insert data in this format to ClickHouse.
|
||||
[Apache ORC](https://orc.apache.org/) is a columnar storage format widespread in the [Hadoop](https://hadoop.apache.org/) ecosystem.
|
||||
|
||||
### Data Types Matching {#data_types-matching-3}
|
||||
|
||||
The table below shows supported data types and how they match ClickHouse [data types](../sql-reference/data-types/index.md) in `INSERT` queries.
|
||||
The table below shows supported data types and how they match ClickHouse [data types](../sql-reference/data-types/index.md) in `INSERT` and `SELECT` queries.
|
||||
|
||||
| ORC data type (`INSERT`) | ClickHouse data type |
|
||||
|--------------------------|-----------------------------------------------------|
|
||||
| `UINT8`, `BOOL` | [UInt8](../sql-reference/data-types/int-uint.md) |
|
||||
| `INT8` | [Int8](../sql-reference/data-types/int-uint.md) |
|
||||
| `UINT16` | [UInt16](../sql-reference/data-types/int-uint.md) |
|
||||
| `INT16` | [Int16](../sql-reference/data-types/int-uint.md) |
|
||||
| `UINT32` | [UInt32](../sql-reference/data-types/int-uint.md) |
|
||||
| `INT32` | [Int32](../sql-reference/data-types/int-uint.md) |
|
||||
| `UINT64` | [UInt64](../sql-reference/data-types/int-uint.md) |
|
||||
| `INT64` | [Int64](../sql-reference/data-types/int-uint.md) |
|
||||
| `FLOAT`, `HALF_FLOAT` | [Float32](../sql-reference/data-types/float.md) |
|
||||
| `DOUBLE` | [Float64](../sql-reference/data-types/float.md) |
|
||||
| `DATE32` | [Date](../sql-reference/data-types/date.md) |
|
||||
| `DATE64`, `TIMESTAMP` | [DateTime](../sql-reference/data-types/datetime.md) |
|
||||
| `STRING`, `BINARY` | [String](../sql-reference/data-types/string.md) |
|
||||
| `DECIMAL` | [Decimal](../sql-reference/data-types/decimal.md) |
|
||||
| ORC data type (`INSERT`) | ClickHouse data type | ORC data type (`SELECT`) |
|
||||
|--------------------------|-----------------------------------------------------|--------------------------|
|
||||
| `UINT8`, `BOOL` | [UInt8](../sql-reference/data-types/int-uint.md) | `UINT8` |
|
||||
| `INT8` | [Int8](../sql-reference/data-types/int-uint.md) | `INT8` |
|
||||
| `UINT16` | [UInt16](../sql-reference/data-types/int-uint.md) | `UINT16` |
|
||||
| `INT16` | [Int16](../sql-reference/data-types/int-uint.md) | `INT16` |
|
||||
| `UINT32` | [UInt32](../sql-reference/data-types/int-uint.md) | `UINT32` |
|
||||
| `INT32` | [Int32](../sql-reference/data-types/int-uint.md) | `INT32` |
|
||||
| `UINT64` | [UInt64](../sql-reference/data-types/int-uint.md) | `UINT64` |
|
||||
| `INT64` | [Int64](../sql-reference/data-types/int-uint.md) | `INT64` |
|
||||
| `FLOAT`, `HALF_FLOAT` | [Float32](../sql-reference/data-types/float.md) | `FLOAT` |
|
||||
| `DOUBLE` | [Float64](../sql-reference/data-types/float.md) | `DOUBLE` |
|
||||
| `DATE32` | [Date](../sql-reference/data-types/date.md) | `DATE32` |
|
||||
| `DATE64`, `TIMESTAMP` | [DateTime](../sql-reference/data-types/datetime.md) | `TIMESTAMP` |
|
||||
| `STRING`, `BINARY` | [String](../sql-reference/data-types/string.md) | `BINARY` |
|
||||
| `DECIMAL` | [Decimal](../sql-reference/data-types/decimal.md) | `DECIMAL` |
|
||||
| `-` | [Array](../sql-reference/data-types/array.md) | `LIST` |
|
||||
|
||||
ClickHouse supports configurable precision of the `Decimal` type. The `INSERT` query treats the ORC `DECIMAL` type as the ClickHouse `Decimal128` type.
|
||||
|
||||
Unsupported ORC data types: `DATE32`, `TIME32`, `FIXED_SIZE_BINARY`, `JSON`, `UUID`, `ENUM`.
|
||||
Unsupported ORC data types: `TIME32`, `FIXED_SIZE_BINARY`, `JSON`, `UUID`, `ENUM`.
|
||||
|
||||
The data types of ClickHouse table columns don’t have to match the corresponding ORC data fields. When inserting data, ClickHouse interprets data types according to the table above and then [casts](../sql-reference/functions/type-conversion-functions.md#type_conversion_function-cast) the data to the data type set for the ClickHouse table column.
|
||||
|
||||
@ -1321,6 +1322,14 @@ You can insert ORC data from a file into ClickHouse table by the following comma
|
||||
$ cat filename.orc | clickhouse-client --query="INSERT INTO some_table FORMAT ORC"
|
||||
```
|
||||
|
||||
### Selecting Data {#selecting-data-2}
|
||||
|
||||
You can select data from a ClickHouse table and save them into some file in the ORC format by the following command:
|
||||
|
||||
``` bash
|
||||
$ clickhouse-client --query="SELECT * FROM {some_table} FORMAT ORC" > {filename.orc}
|
||||
```
|
||||
|
||||
To exchange data with Hadoop, you can use [HDFS table engine](../engines/table-engines/integrations/hdfs.md).
|
||||
|
||||
## LineAsString {#lineasstring}
|
||||
|
@ -12,9 +12,12 @@ toc_title: Adopters
|
||||
|---------|----------|---------|--------------|------------------------------------------------------------------------------|-----------|
|
||||
| <a href="https://2gis.ru" class="favicon">2gis</a> | Maps | Monitoring | — | — | [Talk in Russian, July 2019](https://youtu.be/58sPkXfq6nw) |
|
||||
| <a href="https://getadmiral.com/" class="favicon">Admiral</a> | Martech | Engagement Management | — | — | [Webinar Slides, June 2020](https://altinity.com/presentations/2020/06/16/big-data-in-real-time-how-clickhouse-powers-admirals-visitor-relationships-for-publishers) |
|
||||
| <a href="http://www.adscribe.tv/" class="favicon">AdScribe</a> | Ads | TV Analytics | — | — | [A quote from CTO](https://altinity.com/24x7-support/) |
|
||||
| <a href="https://cn.aliyun.com/" class="favicon">Alibaba Cloud</a> | Cloud | Managed Service | — | — | [Official Website](https://help.aliyun.com/product/144466.html) |
|
||||
| <a href="https://alohabrowser.com/" class="favicon">Aloha Browser</a> | Mobile App | Browser backend | — | — | [Slides in Russian, May 2019](https://presentations.clickhouse.tech/meetup22/aloha.pdf) |
|
||||
| <a href="https://altinity.com/" class="favicon">Altinity</a> | Cloud, SaaS | Main product | — | — | [Official Website](https://altinity.com/) |
|
||||
| <a href="https://amadeus.com/" class="favicon">Amadeus</a> | Travel | Analytics | — | — | [Press Release, April 2018](https://www.altinity.com/blog/2018/4/5/amadeus-technologies-launches-investment-and-insights-tool-based-on-machine-learning-and-strategy-algorithms) |
|
||||
| <a href="https://apiroad.net/" class="favicon">ApiRoad</a> | API marketplace | Analytics | — | — | [Blog post, Nov 2018, Mar 2020](https://pixeljets.com/blog/clickhouse-vs-elasticsearch/) |
|
||||
| <a href="https://www.appsflyer.com" class="favicon">Appsflyer</a> | Mobile analytics | Main product | — | — | [Talk in Russian, July 2019](https://www.youtube.com/watch?v=M3wbRlcpBbY) |
|
||||
| <a href="https://arenadata.tech/" class="favicon">ArenaData</a> | Data Platform | Main product | — | — | [Slides in Russian, December 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup38/indexes.pdf) |
|
||||
| <a href="https://avito.ru/" class="favicon">Avito</a> | Classifieds | Monitoring | — | — | [Meetup, April 2020](https://www.youtube.com/watch?v=n1tm4j4W8ZQ) |
|
||||
@ -37,6 +40,7 @@ toc_title: Adopters
|
||||
| <a href="https://www.creditx.com" class="favicon">CraiditX 氪信</a> | Finance AI | Analysis | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup33/udf.pptx) |
|
||||
| <a href="https://crazypanda.ru/en/" class="favicon">Crazypanda</a> | Games | | — | — | Live session on ClickHouse meetup |
|
||||
| <a href="https://www.criteo.com/" class="favicon">Criteo</a> | Retail | Main product | — | — | [Slides in English, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup18/3_storetail.pptx) |
|
||||
| <a href="https://cryptology.com/" class="favicon">Cryptology</a> | Digital Assets Trading Platform | — | — | — | [Job advertisement, March 2021](https://career.habr.com/companies/cryptology/vacancies) |
|
||||
| <a href="https://www.chinatelecomglobal.com/" class="favicon">Dataliance for China Telecom</a> | Telecom | Analytics | — | — | [Slides in Chinese, January 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup12/telecom.pdf) |
|
||||
| <a href="https://db.com" class="favicon">Deutsche Bank</a> | Finance | BI Analytics | — | — | [Slides in English, October 2019](https://bigdatadays.ru/wp-content/uploads/2019/10/D2-H3-3_Yakunin-Goihburg.pdf) |
|
||||
| <a href="https://deeplay.io/eng/" class="favicon">Deeplay</a> | Gaming Analytics | — | — | — | [Job advertisement, 2020](https://career.habr.com/vacancies/1000062568) |
|
||||
@ -49,11 +53,13 @@ toc_title: Adopters
|
||||
| <a href="https://fun.co/rp" class="favicon">FunCorp</a> | Games | | — | 14 bn records/day as of Jan 2021 | [Article](https://www.altinity.com/blog/migrating-from-redshift-to-clickhouse) |
|
||||
| <a href="https://geniee.co.jp" class="favicon">Geniee</a> | Ad network | Main product | — | — | [Blog post in Japanese, July 2017](https://tech.geniee.co.jp/entry/2017/07/20/160100) |
|
||||
| <a href="https://www.genotek.ru/" class="favicon">Genotek</a> | Bioinformatics | Main product | — | — | [Video, August 2020](https://youtu.be/v3KyZbz9lEE) |
|
||||
| <a href="https://glaber.io/" class="favicon">Glaber</a> | Monitoring | Main product | — | — | [Website](https://glaber.io/) |
|
||||
| <a href="https://www.huya.com/" class="favicon">HUYA</a> | Video Streaming | Analytics | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/7.%20ClickHouse万亿数据分析实践%20李本旺(sundy-li)%20虎牙.pdf) |
|
||||
| <a href="https://www.the-ica.com/" class="favicon">ICA</a> | FinTech | Risk Management | — | — | [Blog Post in English, Sep 2020](https://altinity.com/blog/clickhouse-vs-redshift-performance-for-fintech-risk-management?utm_campaign=ClickHouse%20vs%20RedShift&utm_content=143520807&utm_medium=social&utm_source=twitter&hss_channel=tw-3894792263) |
|
||||
| <a href="https://www.idealista.com" class="favicon">Idealista</a> | Real Estate | Analytics | — | — | [Blog Post in English, April 2019](https://clickhouse.tech/blog/en/clickhouse-meetup-in-madrid-on-april-2-2019) |
|
||||
| <a href="https://www.infovista.com/" class="favicon">Infovista</a> | Networks | Analytics | — | — | [Slides in English, October 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup30/infovista.pdf) |
|
||||
| <a href="https://www.innogames.com" class="favicon">InnoGames</a> | Games | Metrics, Logging | — | — | [Slides in Russian, September 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup28/graphite_and_clickHouse.pdf) |
|
||||
| <a href="https://instabug.com/" class="favicon">Instabug</a> | APM Platform | Main product | — | — | [A quote from Co-Founder](https://altinity.com/) |
|
||||
| <a href="https://www.instana.com" class="favicon">Instana</a> | APM Platform | Main product | — | — | [Twitter post](https://twitter.com/mieldonkers/status/1248884119158882304) |
|
||||
| <a href="https://integros.com" class="favicon">Integros</a> | Platform for video services | Analytics | — | — | [Slides in Russian, May 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup22/strategies.pdf) |
|
||||
| <a href="https://ippon.tech" class="favicon">Ippon Technologies</a> | Technology Consulting | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=205) |
|
||||
@ -65,15 +71,19 @@ toc_title: Adopters
|
||||
| <a href="https://www.lbl.gov" class="favicon">Lawrence Berkeley National Laboratory</a> | Research | Traffic analysis | 1 server | 11.8 TiB | [Slides in English, April 2019](https://www.smitasin.com/presentations/2019-04-17_DOE-NSM.pdf) |
|
||||
| <a href="https://lifestreet.com/" class="favicon">LifeStreet</a> | Ad network | Main product | 75 servers (3 replicas) | 5.27 PiB | [Blog post in Russian, February 2017](https://habr.com/en/post/322620/) |
|
||||
| <a href="https://mcs.mail.ru/" class="favicon">Mail.ru Cloud Solutions</a> | Cloud services | Main product | — | — | [Article in Russian](https://mcs.mail.ru/help/db-create/clickhouse#) |
|
||||
| <a href="https://maxilect.com/" class="favicon">MAXILECT</a> | Ad Tech, Blockchain, ML, AI | — | — | — | [Job advertisement, 2021](https://www.linkedin.com/feed/update/urn:li:activity:6780842017229430784/) |
|
||||
| <a href="https://tech.mymarilyn.ru" class="favicon">Marilyn</a> | Advertising | Statistics | — | — | [Talk in Russian, June 2017](https://www.youtube.com/watch?v=iXlIgx2khwc) |
|
||||
| <a href="https://mellodesign.ru/" class="favicon">Mello</a> | Marketing | Analytics | 1 server | — | [Article, Oct 2020](https://vc.ru/marketing/166180-razrabotka-tipovogo-otcheta-skvoznoy-analitiki) |
|
||||
| <a href="https://www.messagebird.com" class="favicon">MessageBird</a> | Telecommunications | Statistics | — | — | [Slides in English, November 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup20/messagebird.pdf) |
|
||||
| <a href="https://www.mindsdb.com/" class="favicon">MindsDB</a> | Machine Learning | Main Product | — | — | [Official Website](https://www.mindsdb.com/blog/machine-learning-models-as-tables-in-ch) |x
|
||||
| <a href="https://mux.com/" class="favicon">MUX</a> | Online Video | Video Analytics | — | — | [Talk in English, August 2019](https://altinity.com/presentations/2019/8/13/how-clickhouse-became-the-default-analytics-database-for-mux/) |
|
||||
| <a href="https://www.mgid.com/" class="favicon">MGID</a> | Ad network | Web-analytics | — | — | [Blog post in Russian, April 2020](http://gs-studio.com/news-about-it/32777----clickhouse---c) |
|
||||
| <a href="https://www.netskope.com/" class="favicon">Netskope</a> | Network Security | — | — | — | [Job advertisement, March 2021](https://www.mendeley.com/careers/job/senior-software-developer-backend-developer-1346348) |
|
||||
| <a href="https://niclabs.cl/" class="favicon">NIC Labs</a> | Network Monitoring | RaTA-DNS | — | — | [Blog post, March 2021](https://niclabs.cl/ratadns/2021/03/Clickhouse) |
|
||||
| <a href="https://getnoc.com/" class="favicon">NOC Project</a> | Network Monitoring | Analytics | Main Product | — | [Official Website](https://getnoc.com/features/big-data/) |
|
||||
| <a href="https://www.nuna.com/" class="favicon">Nuna Inc.</a> | Health Data Analytics | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=170) |
|
||||
| <a href="https://www.oneapm.com/" class="favicon">OneAPM</a> | Monitorings and Data Analysis | Main product | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/8.%20clickhouse在OneAPM的应用%20杜龙.pdf) |
|
||||
| <a href="https://corp.ozon.com/" class="favicon">OZON</a> | E-commerce | — | — | — | [Official website](https://job.ozon.ru/vacancy/razrabotchik-clickhouse-ekspluatatsiya-40991870/) |
|
||||
| <a href="https://panelbear.com/" class="favicon">Panelbear | Analytics | Monitoring and Analytics | — | — | [Tech Stack, November 2020](https://panelbear.com/blog/tech-stack/) |
|
||||
| <a href="https://www.percent.cn/" class="favicon">Percent 百分点</a> | Analytics | Main Product | — | — | [Slides in Chinese, June 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup24/4.%20ClickHouse万亿数据双中心的设计与实践%20.pdf) |
|
||||
| <a href="https://www.percona.com/" class="favicon">Percona</a> | Performance analysis | Percona Monitoring and Management | — | — | [Official website, Mar 2020](https://www.percona.com/blog/2020/03/30/advanced-query-analysis-in-percona-monitoring-and-management-with-direct-clickhouse-access/) |
|
||||
@ -90,14 +100,17 @@ toc_title: Adopters
|
||||
| <a href="https://rspamd.com/" class="favicon">Rspamd</a> | Antispam | Analytics | — | — | [Official Website](https://rspamd.com/doc/modules/clickhouse.html) |
|
||||
| <a href="https://rusiem.com/en" class="favicon">RuSIEM</a> | SIEM | Main Product | — | — | [Official Website](https://rusiem.com/en/products/architecture) |
|
||||
| <a href="https://www.s7.ru" class="favicon">S7 Airlines</a> | Airlines | Metrics, Logging | — | — | [Talk in Russian, March 2019](https://www.youtube.com/watch?v=nwG68klRpPg&t=15s) |
|
||||
| <a href="https://www.sberbank.com/index" class="favicon">Sber</a> | Banking, Fintech, Retail, Cloud, Media | — | — | — | [Job advertisement, March 2021](https://career.habr.com/vacancies/1000073536) |
|
||||
| <a href="https://www.scireum.de/" class="favicon">scireum GmbH</a> | e-Commerce | Main product | — | — | [Talk in German, February 2020](https://www.youtube.com/watch?v=7QWAn5RbyR4) |
|
||||
| <a href="https://segment.com/" class="favicon">Segment</a> | Data processing | Main product | 9 * i3en.3xlarge nodes 7.5TB NVME SSDs, 96GB Memory, 12 vCPUs | — | [Slides, 2019](https://slides.com/abraithwaite/segment-clickhouse) |
|
||||
| <a href="https://sembot.io/" class="favicon">sembot.io</a> | Shopping Ads | — | — | — | A comment on LinkedIn, 2020 |
|
||||
| <a href="https://www.semrush.com/" class="favicon">SEMrush</a> | Marketing | Main product | — | — | [Slides in Russian, August 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup17/5_semrush.pdf) |
|
||||
| <a href="https://sentry.io/" class="favicon">Sentry</a> | Software Development | Main product | — | — | [Blog Post in English, May 2019](https://blog.sentry.io/2019/05/16/introducing-snuba-sentrys-new-search-infrastructure) |
|
||||
| <a href="https://seo.do/" class="favicon">seo.do</a> | Analytics | Main product | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup35/CH%20Presentation-%20Metehan%20Çetinkaya.pdf) |
|
||||
| <a href="http://www.sgk.gov.tr/wps/portal/sgk/tr" class="favicon">SGK</a> | Goverment Social Security | Analytics | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup35/ClickHouse%20Meetup-Ramazan%20POLAT.pdf) |
|
||||
| <a href="http://english.sina.com/index.html" class="favicon">Sina</a> | News | — | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/6.%20ClickHouse最佳实践%20高鹏_新浪.pdf) |
|
||||
| <a href="https://smi2.ru/" class="favicon">SMI2</a> | News | Analytics | — | — | [Blog Post in Russian, November 2017](https://habr.com/ru/company/smi2/blog/314558/) |
|
||||
| <a href="https://www.spark.co.nz/" class="favicon">Spark New Zealand</a> | Telecommunications | Security Operations | — | — | [Blog Post, Feb 2020](https://blog.n0p.me/2020/02/2020-02-05-dnsmonster/) |
|
||||
| <a href="https://www.splunk.com/" class="favicon">Splunk</a> | Business Analytics | Main product | — | — | [Slides in English, January 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup12/splunk.pdf) |
|
||||
| <a href="https://www.spotify.com" class="favicon">Spotify</a> | Music | Experimentation | — | — | [Slides, July 2018](https://www.slideshare.net/glebus/using-clickhouse-for-experimentation-104247173) |
|
||||
| <a href="https://www.staffcop.ru/" class="favicon">Staffcop</a> | Information Security | Main Product | — | — | [Official website, Documentation](https://www.staffcop.ru/sce43) |
|
||||
@ -106,23 +119,31 @@ toc_title: Adopters
|
||||
| <a href="https://www.tencent.com" class="favicon">Tencent</a> | Big Data | Data processing | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/5.%20ClickHouse大数据集群应用_李俊飞腾讯网媒事业部.pdf) |
|
||||
| <a href="https://www.tencent.com" class="favicon">Tencent</a> | Messaging | Logging | — | — | [Talk in Chinese, November 2019](https://youtu.be/T-iVQRuw-QY?t=5050) |
|
||||
| <a href="https://www.tencentmusic.com/" class="favicon">Tencent Music Entertainment (TME)</a> | BigData | Data processing | — | — | [Blog in Chinese, June 2020](https://cloud.tencent.com/developer/article/1637840) |
|
||||
| <a href="https://www.tinybird.co/" class="favicon">Tinybird</a> | Real-time Data Products | Data processing | — | — | [Official website](https://www.tinybird.co/) |
|
||||
| <a href="https://trafficstars.com/" class="favicon">Traffic Stars</a> | AD network | — | — | — | [Slides in Russian, May 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup15/lightning/ninja.pdf) |
|
||||
| <a href="https://www.uber.com" class="favicon">Uber</a> | Taxi | Logging | — | — | [Slides, February 2020](https://presentations.clickhouse.tech/meetup40/uber.pdf) |
|
||||
| <a href="https://hello.utmstat.com/" class="favicon">UTMSTAT</a> | Analytics | Main product | — | — | [Blog post, June 2020](https://vc.ru/tribuna/133956-striming-dannyh-iz-servisa-skvoznoy-analitiki-v-clickhouse) |
|
||||
| <a href="https://vk.com" class="favicon">VKontakte</a> | Social Network | Statistics, Logging | — | — | [Slides in Russian, August 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup17/3_vk.pdf) |
|
||||
| <a href="https://www.vmware.com/" class="favicon">VMWare</a> | Cloud | VeloCloud, SDN | — | — | [Product documentation](https://docs.vmware.com/en/vRealize-Operations-Manager/8.3/com.vmware.vcom.metrics.doc/GUID-A9AD72E1-C948-4CA2-971B-919385AB3CA8.html) |
|
||||
| <a href="https://www.walmartlabs.com/" class="favicon">Walmart Labs</a> | Internet, Retail | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=144) |
|
||||
| <a href="https://wargaming.com/en/" class="favicon">Wargaming</a> | Games | | — | — | [Interview](https://habr.com/en/post/496954/) |
|
||||
| <a href="https://www.wildberries.ru/" class="favicon">Wildberries</a> | E-commerce | | — | — | [Official website](https://it.wildberries.ru/) |
|
||||
| <a href="https://wisebits.com/" class="favicon">Wisebits</a> | IT Solutions | Analytics | — | — | [Slides in Russian, May 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup22/strategies.pdf) |
|
||||
| <a href="https://www.workato.com/" class="favicon">Workato</a> | Automation Software | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=334) |
|
||||
| <a href="https://xenoss.io/" class="favicon">Xenoss</a> | Marketing, Advertising | — | — | — | [Instagram, March 2021](https://www.instagram.com/p/CNATV7qBgB1/) |
|
||||
| <a href="http://www.xiaoxintech.cn/" class="favicon">Xiaoxin Tech</a> | Education | Common purpose | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup33/sync-clickhouse-with-mysql-mongodb.pptx) |
|
||||
| <a href="https://www.ximalaya.com/" class="favicon">Ximalaya</a> | Audio sharing | OLAP | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup33/ximalaya.pdf) |
|
||||
| <a href="https://cloud.yandex.ru/services/managed-clickhouse" class="favicon">Yandex Cloud</a> | Public Cloud | Main product | — | — | [Talk in Russian, December 2019](https://www.youtube.com/watch?v=pgnak9e_E0o) |
|
||||
| <a href="https://cloud.yandex.ru/services/datalens" class="favicon">Yandex DataLens</a> | Business Intelligence | Main product | — | — | [Slides in Russian, December 2019](https://presentations.clickhouse.tech/meetup38/datalens.pdf) |
|
||||
| <a href="https://market.yandex.ru/" class="favicon">Yandex Market</a> | e-Commerce | Metrics, Logging | — | — | [Talk in Russian, January 2019](https://youtu.be/_l1qP0DyBcA?t=478) |
|
||||
| <a href="https://metrica.yandex.com" class="favicon">Yandex Metrica</a> | Web analytics | Main product | 630 servers in one cluster, 360 servers in another cluster, 1862 servers in one department | 133 PiB / 8.31 PiB / 120 trillion records | [Slides, February 2020](https://presentations.clickhouse.tech/meetup40/introduction/#13) |
|
||||
| <a href="https://www.yotascale.com/" class="favicon">Yotascale</a> | Cloud | Data pipeline | — | 2 bn records/day | [LinkedIn (Accomplishments)](https://www.linkedin.com/in/adilsaleem/) |
|
||||
| <a href="https://htc-cs.ru/" class="favicon">ЦВТ</a> | Software Development | Metrics, Logging | — | — | [Blog Post, March 2019, in Russian](https://vc.ru/dev/62715-kak-my-stroili-monitoring-na-prometheus-clickhouse-i-elk) |
|
||||
| <a href="https://mkb.ru/" class="favicon">МКБ</a> | Bank | Web-system monitoring | — | — | [Slides in Russian, September 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup28/mkb.pdf) |
|
||||
| <a href="https://cft.ru/" class="favicon">ЦФТ</a> | Banking, Financial products, Payments | — | — | — | [Meetup in Russian, April 2020](https://team.cft.ru/events/162) |
|
||||
| <a href="https://promo.croc.ru/digitalworker" class="favicon">Цифровой Рабочий</a> | Industrial IoT, Analytics | — | — | — | [Blog post in Russian, March 2021](https://habr.com/en/company/croc/blog/548018/) |
|
||||
| <a href="https://www.kakaocorp.com/" class="favicon">kakaocorp</a> | Internet company | — | — | — | [if(kakao)2020 conference](https://if.kakao.com/session/117) |
|
||||
| <a href="https://shop.okraina.ru/" class="favicon">ООО «МПЗ Богородский»</a> | Agriculture | — | — | — | [Article in Russian, November 2020](https://cloud.yandex.ru/cases/okraina) |
|
||||
| <a href="https://www.tesla.com/" class="favicon">Tesla</a> | Electric vehicle and clean energy company | — | — | — | [Vacancy description, March 2021](https://news.ycombinator.com/item?id=26306170) |
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/introduction/adopters/) <!--hide-->
|
||||
|
@ -502,7 +502,15 @@ On hosts with low RAM and swap, you possibly need setting `max_server_memory_usa
|
||||
|
||||
## max_concurrent_queries {#max-concurrent-queries}
|
||||
|
||||
The maximum number of simultaneously processed requests.
|
||||
The maximum number of simultaneously processed queries related to MergeTree table. Queries may be limited by other settings: [max_concurrent_queries_for_all_users](#max-concurrent-queries-for-all-users), [min_marks_to_honor_max_concurrent_queries](#min-marks-to-honor-max-concurrent-queries).
|
||||
|
||||
!!! info "Note"
|
||||
These settings can be modified at runtime and will take effect immediately. Queries that are already running will remain unchanged.
|
||||
|
||||
Possible values:
|
||||
|
||||
- Positive integer.
|
||||
- 0 — Disabled.
|
||||
|
||||
**Example**
|
||||
|
||||
@ -530,6 +538,21 @@ Default value: `0` that means no limit.
|
||||
|
||||
- [max_concurrent_queries](#max-concurrent-queries)
|
||||
|
||||
## min_marks_to_honor_max_concurrent_queries {#min-marks-to-honor-max-concurrent-queries}
|
||||
|
||||
The minimal number of marks read by the query for applying the [max_concurrent_queries](#max-concurrent-queries) setting.
|
||||
|
||||
Possible values:
|
||||
|
||||
- Positive integer.
|
||||
- 0 — Disabled.
|
||||
|
||||
**Example**
|
||||
|
||||
``` xml
|
||||
<min_marks_to_honor_max_concurrent_queries>10</min_marks_to_honor_max_concurrent_queries>
|
||||
```
|
||||
|
||||
## max_connections {#max-connections}
|
||||
|
||||
The maximum number of inbound connections.
|
||||
|
@ -769,6 +769,38 @@ Example:
|
||||
log_query_threads=1
|
||||
```
|
||||
|
||||
## log_comment {#settings-log-comment}
|
||||
|
||||
Specifies the value for the `log_comment` field of the [system.query_log](../system-tables/query_log.md) table and comment text for the server log.
|
||||
|
||||
It can be used to improve the readability of server logs. Additionally, it helps to select queries related to the test from the `system.query_log` after running [clickhouse-test](../../development/tests.md).
|
||||
|
||||
Possible values:
|
||||
|
||||
- Any string no longer than [max_query_size](#settings-max_query_size). If length is exceeded, the server throws an exception.
|
||||
|
||||
Default value: empty string.
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SET log_comment = 'log_comment test', log_queries = 1;
|
||||
SELECT 1;
|
||||
SYSTEM FLUSH LOGS;
|
||||
SELECT type, query FROM system.query_log WHERE log_comment = 'log_comment test' AND event_date >= yesterday() ORDER BY event_time DESC LIMIT 2;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─type────────┬─query─────┐
|
||||
│ QueryStart │ SELECT 1; │
|
||||
│ QueryFinish │ SELECT 1; │
|
||||
└─────────────┴───────────┘
|
||||
```
|
||||
|
||||
## max_insert_block_size {#settings-max_insert_block_size}
|
||||
|
||||
The size of blocks (in a count of rows) to form for insertion into a table.
|
||||
@ -1514,6 +1546,14 @@ FORMAT PrettyCompactMonoBlock
|
||||
|
||||
Default value: 0
|
||||
|
||||
## optimize_skip_unused_shards_limit {#optimize-skip-unused-shards-limit}
|
||||
|
||||
Limit for number of sharding key values, turns off `optimize_skip_unused_shards` if the limit is reached.
|
||||
|
||||
Too many values may require significant amount for processing, while the benefit is doubtful, since if you have huge number of values in `IN (...)`, then most likely the query will be sent to all shards anyway.
|
||||
|
||||
Default value: 1000
|
||||
|
||||
## optimize_skip_unused_shards {#optimize-skip-unused-shards}
|
||||
|
||||
Enables or disables skipping of unused shards for [SELECT](../../sql-reference/statements/select/index.md) queries that have sharding key condition in `WHERE/PREWHERE` (assuming that the data is distributed by sharding key, otherwise does nothing).
|
||||
@ -1874,7 +1914,7 @@ Default value: `0`.
|
||||
|
||||
Enables or disables random shard insertion into a [Distributed](../../engines/table-engines/special/distributed.md#distributed) table when there is no distributed key.
|
||||
|
||||
By default, when inserting data into a `Distributed` table with more than one shard, the ClickHouse server will any insertion request if there is no distributed key. When `insert_distributed_one_random_shard = 1`, insertions are allowed and data is forwarded randomly among all shards.
|
||||
By default, when inserting data into a `Distributed` table with more than one shard, the ClickHouse server will reject any insertion request if there is no distributed key. When `insert_distributed_one_random_shard = 1`, insertions are allowed and data is forwarded randomly among all shards.
|
||||
|
||||
Possible values:
|
||||
|
||||
@ -2728,11 +2768,11 @@ Default value: `0`.
|
||||
|
||||
## engine_file_truncate_on_insert {#engine-file-truncate-on-insert}
|
||||
|
||||
Enables or disables truncate before insert in file engine tables.
|
||||
Enables or disables truncate before insert in [File](../../engines/table-engines/special/file.md) engine tables.
|
||||
|
||||
Possible values:
|
||||
- 0 — Disabled.
|
||||
- 1 — Enabled.
|
||||
- 0 — `INSERT` query appends new data to the end of the file.
|
||||
- 1 — `INSERT` replaces existing content of the file with the new data.
|
||||
|
||||
Default value: `0`.
|
||||
|
||||
@ -2747,4 +2787,39 @@ Possible values:
|
||||
|
||||
Default value: `0`.
|
||||
|
||||
## allow_experimental_live_view {#allow-experimental-live-view}
|
||||
|
||||
Allows creation of experimental [live views](../../sql-reference/statements/create/view.md#live-view).
|
||||
|
||||
Possible values:
|
||||
|
||||
- 0 — Working with live views is disabled.
|
||||
- 1 — Working with live views is enabled.
|
||||
|
||||
Default value: `0`.
|
||||
|
||||
## live_view_heartbeat_interval {#live-view-heartbeat-interval}
|
||||
|
||||
Sets the heartbeat interval in seconds to indicate [live view](../../sql-reference/statements/create/view.md#live-view) is alive .
|
||||
|
||||
Default value: `15`.
|
||||
|
||||
## max_live_view_insert_blocks_before_refresh {#max-live-view-insert-blocks-before-refresh}
|
||||
|
||||
Sets the maximum number of inserted blocks after which mergeable blocks are dropped and query for [live view](../../sql-reference/statements/create/view.md#live-view) is re-executed.
|
||||
|
||||
Default value: `64`.
|
||||
|
||||
## temporary_live_view_timeout {#temporary-live-view-timeout}
|
||||
|
||||
Sets the interval in seconds after which [live view](../../sql-reference/statements/create/view.md#live-view) with timeout is deleted.
|
||||
|
||||
Default value: `5`.
|
||||
|
||||
## periodic_live_view_refresh {#periodic-live-view-refresh}
|
||||
|
||||
Sets the interval in seconds after which periodically refreshed [live view](../../sql-reference/statements/create/view.md#live-view) is forced to refresh.
|
||||
|
||||
Default value: `60`.
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/operations/settings/settings/) <!-- hide -->
|
||||
|
@ -9,7 +9,7 @@ Columns:
|
||||
- `value` ([UInt64](../../sql-reference/data-types/int-uint.md)) — the number of times this error has been happened.
|
||||
- `last_error_time` ([DateTime](../../sql-reference/data-types/datetime.md)) — time when the last error happened.
|
||||
- `last_error_message` ([String](../../sql-reference/data-types/string.md)) — message for the last error.
|
||||
- `last_error_stacktrace` ([String](../../sql-reference/data-types/string.md)) — stacktrace for the last error.
|
||||
- `last_error_trace` ([Array(UInt64)](../../sql-reference/data-types/array.md)) — A [stack trace](https://en.wikipedia.org/wiki/Stack_trace) which represents a list of physical addresses where the called methods are stored.
|
||||
- `remote` ([UInt8](../../sql-reference/data-types/int-uint.md)) — remote exception (i.e. received during one of the distributed query).
|
||||
|
||||
**Example**
|
||||
@ -25,3 +25,12 @@ LIMIT 1
|
||||
│ CANNOT_OPEN_FILE │ 76 │ 1 │
|
||||
└──────────────────┴──────┴───────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
WITH arrayMap(x -> demangle(addressToSymbol(x)), last_error_trace) AS all
|
||||
SELECT name, arrayStringConcat(all, '\n') AS res
|
||||
FROM system.errors
|
||||
LIMIT 1
|
||||
SETTINGS allow_introspection_functions=1\G
|
||||
```
|
||||
|
||||
|
@ -243,7 +243,7 @@ The function works according to the algorithm:
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
windowFunnel(window, [mode])(timestamp, cond1, cond2, ..., condN)
|
||||
windowFunnel(window, [mode, [mode, ... ]])(timestamp, cond1, cond2, ..., condN)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
@ -253,9 +253,11 @@ windowFunnel(window, [mode])(timestamp, cond1, cond2, ..., condN)
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `window` — Length of the sliding window. The unit of `window` depends on the `timestamp` itself and varies. Determined using the expression `timestamp of cond2 <= timestamp of cond1 + window`.
|
||||
- `mode` — It is an optional argument.
|
||||
- `'strict'` — When the `'strict'` is set, the windowFunnel() applies conditions only for the unique values.
|
||||
- `window` — Length of the sliding window, it is the time interval between first condition and last condition. The unit of `window` depends on the `timestamp` itself and varies. Determined using the expression `timestamp of cond1 <= timestamp of cond2 <= ... <= timestamp of condN <= timestamp of cond1 + window`.
|
||||
- `mode` — It is an optional argument. One or more modes can be set.
|
||||
- `'strict'` — If same condition holds for sequence of events then such non-unique events would be skipped.
|
||||
- `'strict_order'` — Don't allow interventions of other events. E.g. in the case of `A->B->D->C`, it stops finding `A->B->C` at the `D` and the max event level is 2.
|
||||
- `'strict_increase'` — Apply conditions only to events with strictly increasing timestamps.
|
||||
|
||||
**Returned value**
|
||||
|
||||
|
@ -320,8 +320,6 @@ Similar to `cache`, but stores data on SSD and index in RAM.
|
||||
<write_buffer_size>1048576</write_buffer_size>
|
||||
<!-- Path where cache file will be stored. -->
|
||||
<path>/var/lib/clickhouse/clickhouse_dictionaries/test_dict</path>
|
||||
<!-- Max number on stored keys in the cache. Rounded up to a power of two. -->
|
||||
<max_stored_keys>1048576</max_stored_keys>
|
||||
</ssd_cache>
|
||||
</layout>
|
||||
```
|
||||
@ -329,8 +327,8 @@ Similar to `cache`, but stores data on SSD and index in RAM.
|
||||
or
|
||||
|
||||
``` sql
|
||||
LAYOUT(CACHE(BLOCK_SIZE 4096 FILE_SIZE 16777216 READ_BUFFER_SIZE 1048576
|
||||
PATH /var/lib/clickhouse/clickhouse_dictionaries/test_dict MAX_STORED_KEYS 1048576))
|
||||
LAYOUT(SSD_CACHE(BLOCK_SIZE 4096 FILE_SIZE 16777216 READ_BUFFER_SIZE 1048576
|
||||
PATH /var/lib/clickhouse/clickhouse_dictionaries/test_dict))
|
||||
```
|
||||
|
||||
### complex_key_ssd_cache {#complex-key-ssd-cache}
|
||||
|
35
docs/en/sql-reference/functions/files.md
Normal file
35
docs/en/sql-reference/functions/files.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
toc_priority: 43
|
||||
toc_title: Files
|
||||
---
|
||||
|
||||
# Functions for Working with Files {#functions-for-working-with-files}
|
||||
|
||||
## file {#file}
|
||||
|
||||
Reads file as a String. The file content is not parsed, so any information is read as one string and placed into the specified column.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
file(path)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `path` — The relative path to the file from [user_files_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path). Path to file support following wildcards: `*`, `?`, `{abc,def}` and `{N..M}` where `N`, `M` — numbers, `'abc', 'def'` — strings.
|
||||
|
||||
**Example**
|
||||
|
||||
Inserting data from files a.txt and b.txt into a table as strings:
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
INSERT INTO table SELECT file('a.txt'), file('b.txt');
|
||||
```
|
||||
|
||||
**See Also**
|
||||
|
||||
- [user_files_path](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-user_files_path)
|
||||
- [file](../table-functions/file.md)
|
@ -394,3 +394,55 @@ Result:
|
||||
└──────────────────┴────────────────────┘
|
||||
```
|
||||
|
||||
## isIPAddressInRange {#isipaddressinrange}
|
||||
|
||||
Determines if an IP address is contained in a network represented in the [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) notation. Returns `1` if true, or `0` otherwise.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
isIPAddressInRange(address, prefix)
|
||||
```
|
||||
|
||||
This function accepts both IPv4 and IPv6 addresses (and networks) represented as strings. It returns `0` if the IP version of the address and the CIDR don't match.
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `address` — An IPv4 or IPv6 address. [String](../../sql-reference/data-types/string.md).
|
||||
- `prefix` — An IPv4 or IPv6 network prefix in CIDR. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- `1` or `0`.
|
||||
|
||||
Type: [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT isIPAddressInRange('127.0.0.1', '127.0.0.0/8')
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─isIPAddressInRange('127.0.0.1', '127.0.0.0/8')─┐
|
||||
│ 1 │
|
||||
└────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT isIPAddressInRange('127.0.0.1', 'ffff::/16')
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─isIPAddressInRange('127.0.0.1', 'ffff::/16')─┐
|
||||
│ 0 │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
|
@ -12,7 +12,9 @@ The search is case-sensitive by default in all these functions. There are separa
|
||||
|
||||
## position(haystack, needle), locate(haystack, needle) {#position}
|
||||
|
||||
Returns the position (in bytes) of the found substring in the string, starting from 1.
|
||||
Searches for the substring `needle` in the string `haystack`.
|
||||
|
||||
Returns the position (in bytes) of the found substring in the string, starting from 1.
|
||||
|
||||
For a case-insensitive search, use the function [positionCaseInsensitive](#positioncaseinsensitive).
|
||||
|
||||
@ -20,15 +22,22 @@ For a case-insensitive search, use the function [positionCaseInsensitive](#posit
|
||||
|
||||
``` sql
|
||||
position(haystack, needle[, start_pos])
|
||||
```
|
||||
```
|
||||
|
||||
``` sql
|
||||
position(needle IN haystack)
|
||||
```
|
||||
|
||||
Alias: `locate(haystack, needle[, start_pos])`.
|
||||
|
||||
!!! note "Note"
|
||||
Syntax of `position(needle IN haystack)` provides SQL-compatibility, the function works the same way as to `position(haystack, needle)`.
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `haystack` — String, in which substring will to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal).
|
||||
- `needle` — Substring to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal).
|
||||
- `start_pos` — Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md).
|
||||
- `start_pos` – Position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md). Optional.
|
||||
|
||||
**Returned values**
|
||||
|
||||
@ -83,6 +92,36 @@ Result:
|
||||
└───────────────────────────────┘
|
||||
```
|
||||
|
||||
**Examples for POSITION(needle IN haystack) syntax**
|
||||
|
||||
Query:
|
||||
|
||||
```sql
|
||||
SELECT 3 = position('c' IN 'abc');
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```text
|
||||
┌─equals(3, position('abc', 'c'))─┐
|
||||
│ 1 │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
```sql
|
||||
SELECT 6 = position('/' IN s) FROM (SELECT 'Hello/World' AS s);
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```text
|
||||
┌─equals(6, position(s, '/'))─┐
|
||||
│ 1 │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
## positionCaseInsensitive {#positioncaseinsensitive}
|
||||
|
||||
The same as [position](#position) returns the position (in bytes) of the found substring in the string, starting from 1. Use the function for a case-insensitive search.
|
||||
@ -772,4 +811,3 @@ Result:
|
||||
│ 2 │
|
||||
└───────────────────────────────┘
|
||||
```
|
||||
|
||||
|
@ -385,8 +385,6 @@ reinterpretAsUUID(fixed_string)
|
||||
|
||||
- `fixed_string` — Big-endian byte string. [FixedString](../../sql-reference/data-types/fixedstring.md#fixedstring).
|
||||
|
||||
## reinterpret(x, T) {#type_conversion_function-reinterpret}
|
||||
|
||||
**Returned value**
|
||||
|
||||
- The UUID type value. [UUID](../../sql-reference/data-types/uuid.md#uuid-data-type).
|
||||
@ -398,9 +396,7 @@ String to UUID.
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT reinterpret(toInt8(-1), 'UInt8') as int_to_uint,
|
||||
reinterpret(toInt8(1), 'Float32') as int_to_float,
|
||||
reinterpret('1', 'UInt32') as string_to_int;
|
||||
SELECT reinterpretAsUUID(reverse(unhex('000102030405060708090a0b0c0d0e0f')));
|
||||
```
|
||||
|
||||
Result:
|
||||
@ -431,15 +427,51 @@ Result:
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## reinterpret(x, T) {#type_conversion_function-reinterpret}
|
||||
|
||||
Use the same source in-memory bytes sequence for `x` value and reinterpret it to destination type
|
||||
|
||||
Query:
|
||||
```sql
|
||||
SELECT reinterpret(toInt8(-1), 'UInt8') as int_to_uint,
|
||||
reinterpret(toInt8(1), 'Float32') as int_to_float,
|
||||
reinterpret('1', 'UInt32') as string_to_int;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```
|
||||
┌─int_to_uint─┬─int_to_float─┬─string_to_int─┐
|
||||
│ 255 │ 1e-45 │ 49 │
|
||||
└─────────────┴──────────────┴───────────────┘
|
||||
```
|
||||
|
||||
## CAST(x, T) {#type_conversion_function-cast}
|
||||
|
||||
Converts input value `x` to the `T` data type.
|
||||
Converts input value `x` to the `T` data type. Unlike to `reinterpret` function use external representation of `x` value.
|
||||
|
||||
The syntax `CAST(x AS t)` is also supported.
|
||||
|
||||
Note, that if value `x` does not fit the bounds of type T, the function overflows. For example, CAST(-1, 'UInt8') returns 255.
|
||||
|
||||
**Example**
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
cast(toInt8(-1), 'UInt8') AS cast_int_to_uint,
|
||||
cast(toInt8(1), 'Float32') AS cast_int_to_float,
|
||||
cast('1', 'UInt32') AS cast_string_to_int
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```
|
||||
┌─cast_int_to_uint─┬─cast_int_to_float─┬─cast_string_to_int─┐
|
||||
│ 255 │ 1 │ 1 │
|
||||
└──────────────────┴───────────────────┴────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
@ -634,6 +666,7 @@ Result:
|
||||
```
|
||||
|
||||
## parseDateTimeBestEffort {#parsedatetimebesteffort}
|
||||
## parseDateTime32BestEffort {#parsedatetime32besteffort}
|
||||
|
||||
Converts a date and time in the [String](../../sql-reference/data-types/string.md) representation to [DateTime](../../sql-reference/data-types/datetime.md#data_type-datetime) data type.
|
||||
|
||||
@ -822,10 +855,12 @@ Result:
|
||||
```
|
||||
|
||||
## parseDateTimeBestEffortOrNull {#parsedatetimebesteffortornull}
|
||||
## parseDateTime32BestEffortOrNull {#parsedatetime32besteffortornull}
|
||||
|
||||
Same as for [parseDateTimeBestEffort](#parsedatetimebesteffort) except that it returns null when it encounters a date format that cannot be processed.
|
||||
Same as for [parseDateTimeBestEffort](#parsedatetimebesteffort) except that it returns `NULL` when it encounters a date format that cannot be processed.
|
||||
|
||||
## parseDateTimeBestEffortOrZero {#parsedatetimebesteffortorzero}
|
||||
## parseDateTime32BestEffortOrZero {#parsedatetime32besteffortorzero}
|
||||
|
||||
Same as for [parseDateTimeBestEffort](#parsedatetimebesteffort) except that it returns zero date or zero date time when it encounters a date format that cannot be processed.
|
||||
|
||||
@ -1001,6 +1036,57 @@ Result:
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## parseDateTime64BestEffort {#parsedatetime64besteffort}
|
||||
|
||||
Same as [parseDateTimeBestEffort](#parsedatetimebesteffort) function but also parse milliseconds and microseconds and return `DateTime64(3)` or `DateTime64(6)` data types.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
parseDateTime64BestEffort(time_string [, precision [, time_zone]])
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `time_string` — String containing a date or date with time to convert. [String](../../sql-reference/data-types/string.md).
|
||||
- `precision` — `3` for milliseconds, `6` for microseconds. Default `3`. Optional [UInt8](../../sql-reference/data-types/int-uint.md).
|
||||
- `time_zone` — [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone). The function parses `time_string` according to the timezone. Optional. [String](../../sql-reference/data-types/string.md).
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
```sql
|
||||
SELECT parseDateTime64BestEffort('2021-01-01') AS a, toTypeName(a) AS t
|
||||
UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346') AS a, toTypeName(a) AS t
|
||||
UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346',6) AS a, toTypeName(a) AS t
|
||||
UNION ALL
|
||||
SELECT parseDateTime64BestEffort('2021-01-01 01:01:00.12346',3,'Europe/Moscow') AS a, toTypeName(a) AS t
|
||||
FORMAT PrettyCompactMonoBlcok
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```
|
||||
┌──────────────────────────a─┬─t──────────────────────────────┐
|
||||
│ 2021-01-01 01:01:00.123000 │ DateTime64(3) │
|
||||
│ 2021-01-01 00:00:00.000000 │ DateTime64(3) │
|
||||
│ 2021-01-01 01:01:00.123460 │ DateTime64(6) │
|
||||
│ 2020-12-31 22:01:00.123000 │ DateTime64(3, 'Europe/Moscow') │
|
||||
└────────────────────────────┴────────────────────────────────┘
|
||||
```
|
||||
|
||||
## parseDateTime64BestEffortOrNull {#parsedatetime32besteffortornull}
|
||||
|
||||
Same as for [parseDateTime64BestEffort](#parsedatetime64besteffort) except that it returns `NULL` when it encounters a date format that cannot be processed.
|
||||
|
||||
## parseDateTime64BestEffortOrZero {#parsedatetime64besteffortorzero}
|
||||
|
||||
Same as for [parseDateTime64BestEffort](#parsedatetimebesteffort) except that it returns zero date or zero date time when it encounters a date format that cannot be processed.
|
||||
|
||||
|
||||
## toLowCardinality {#tolowcardinality}
|
||||
|
||||
Converts input parameter to the [LowCardianlity](../../sql-reference/data-types/lowcardinality.md) version of same data type.
|
||||
@ -1009,7 +1095,7 @@ To convert data from the `LowCardinality` data type use the [CAST](#type_convers
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
toLowCardinality(expr)
|
||||
```
|
||||
|
||||
@ -1027,7 +1113,7 @@ Type: `LowCardinality(expr_result_type)`
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
```sql
|
||||
SELECT toLowCardinality('1');
|
||||
```
|
||||
|
||||
@ -1045,7 +1131,8 @@ Result:
|
||||
|
||||
## toUnixTimestamp64Nano {#tounixtimestamp64nano}
|
||||
|
||||
Converts a `DateTime64` to a `Int64` value with fixed sub-second precision. Input value is scaled up or down appropriately depending on it precision. Please note that output value is a timestamp in UTC, not in timezone of `DateTime64`.
|
||||
Converts a `DateTime64` to a `Int64` value with fixed sub-second precision.
|
||||
Input value is scaled up or down appropriately depending on it precision. Please note that output value is a timestamp in UTC, not in timezone of `DateTime64`.
|
||||
|
||||
**Syntax**
|
||||
|
||||
@ -1078,6 +1165,8 @@ Result:
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
WITH toDateTime64('2019-09-16 19:20:12.345678910', 6) AS dt64
|
||||
SELECT toUnixTimestamp64Nano(dt64);
|
||||
|
@ -144,7 +144,7 @@ This query changes the `name` column properties:
|
||||
|
||||
- TTL
|
||||
|
||||
For examples of columns TTL modifying, see [Column TTL](../../engines/table_engines/mergetree_family/mergetree.md#mergetree-column-ttl).
|
||||
For examples of columns TTL modifying, see [Column TTL](../../../engines/table-engines/mergetree-family/mergetree.md#mergetree-column-ttl).
|
||||
|
||||
If the `IF EXISTS` clause is specified, the query won’t return an error if the column doesn’t exist.
|
||||
|
||||
|
@ -68,7 +68,7 @@ To delete a view, use [DROP VIEW](../../../sql-reference/statements/drop.md#drop
|
||||
|
||||
!!! important "Important"
|
||||
This is an experimental feature that may change in backwards-incompatible ways in the future releases.
|
||||
Enable usage of live views and `WATCH` query using `set allow_experimental_live_view = 1`.
|
||||
Enable usage of live views and `WATCH` query using [allow_experimental_live_view](../../../operations/settings/settings.md#allow-experimental-live-view) setting. Input the command `set allow_experimental_live_view = 1`.
|
||||
|
||||
|
||||
```sql
|
||||
@ -90,7 +90,9 @@ Live views work similarly to how a query in a distributed table works. But inste
|
||||
|
||||
See [WITH REFRESH](#live-view-with-refresh) to force periodic updates of a live view that in some cases can be used as a workaround.
|
||||
|
||||
You can watch for changes in the live view query result using the [WATCH](../../../sql-reference/statements/watch.md) query
|
||||
### Monitoring Changes {#live-view-monitoring}
|
||||
|
||||
You can monitor changes in the `LIVE VIEW` query result using [WATCH](../../../sql-reference/statements/watch.md) query.
|
||||
|
||||
```sql
|
||||
WATCH [db.]live_view
|
||||
@ -102,11 +104,10 @@ WATCH [db.]live_view
|
||||
CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
|
||||
CREATE LIVE VIEW lv AS SELECT sum(x) FROM mt;
|
||||
```
|
||||
|
||||
Watch a live view while doing a parallel insert into the source table.
|
||||
|
||||
```sql
|
||||
WATCH lv
|
||||
WATCH lv;
|
||||
```
|
||||
|
||||
```bash
|
||||
@ -128,16 +129,16 @@ INSERT INTO mt VALUES (2);
|
||||
INSERT INTO mt VALUES (3);
|
||||
```
|
||||
|
||||
or add [EVENTS](../../../sql-reference/statements/watch.md#events-clause) clause to just get change events.
|
||||
Or add [EVENTS](../../../sql-reference/statements/watch.md#events-clause) clause to just get change events.
|
||||
|
||||
```sql
|
||||
WATCH [db.]live_view EVENTS
|
||||
WATCH [db.]live_view EVENTS;
|
||||
```
|
||||
|
||||
**Example:**
|
||||
|
||||
```sql
|
||||
WATCH lv EVENTS
|
||||
WATCH lv EVENTS;
|
||||
```
|
||||
|
||||
```bash
|
||||
@ -163,15 +164,15 @@ SELECT * FROM [db.]live_view WHERE ...
|
||||
|
||||
You can force live view refresh using the `ALTER LIVE VIEW [db.]table_name REFRESH` statement.
|
||||
|
||||
### With Timeout {#live-view-with-timeout}
|
||||
### WITH TIMEOUT Clause {#live-view-with-timeout}
|
||||
|
||||
When a live view is create with a `WITH TIMEOUT` clause then the live view will be dropped automatically after the specified number of seconds elapse since the end of the last [WATCH](../../../sql-reference/statements/watch.md) query that was watching the live view.
|
||||
When a live view is created with a `WITH TIMEOUT` clause then the live view will be dropped automatically after the specified number of seconds elapse since the end of the last [WATCH](../../../sql-reference/statements/watch.md) query that was watching the live view.
|
||||
|
||||
```sql
|
||||
CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AS SELECT ...
|
||||
```
|
||||
|
||||
If the timeout value is not specified then the value specified by the `temporary_live_view_timeout` setting is used.
|
||||
If the timeout value is not specified then the value specified by the [temporary_live_view_timeout](../../../operations/settings/settings.md#temporary-live-view-timeout) setting is used.
|
||||
|
||||
**Example:**
|
||||
|
||||
@ -180,7 +181,7 @@ CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
|
||||
CREATE LIVE VIEW lv WITH TIMEOUT 15 AS SELECT sum(x) FROM mt;
|
||||
```
|
||||
|
||||
### With Refresh {#live-view-with-refresh}
|
||||
### WITH REFRESH Clause {#live-view-with-refresh}
|
||||
|
||||
When a live view is created with a `WITH REFRESH` clause then it will be automatically refreshed after the specified number of seconds elapse since the last refresh or trigger.
|
||||
|
||||
@ -188,7 +189,7 @@ When a live view is created with a `WITH REFRESH` clause then it will be automat
|
||||
CREATE LIVE VIEW [db.]table_name WITH REFRESH [value_in_sec] AS SELECT ...
|
||||
```
|
||||
|
||||
If the refresh value is not specified then the value specified by the `periodic_live_view_refresh` setting is used.
|
||||
If the refresh value is not specified then the value specified by the [periodic_live_view_refresh](../../../operations/settings/settings.md#periodic-live-view-refresh) setting is used.
|
||||
|
||||
**Example:**
|
||||
|
||||
@ -231,7 +232,7 @@ WATCH lv
|
||||
Code: 60. DB::Exception: Received from localhost:9000. DB::Exception: Table default.lv doesn't exist..
|
||||
```
|
||||
|
||||
### Usage
|
||||
### Usage {#live-view-usage}
|
||||
|
||||
Most common uses of live view tables include:
|
||||
|
||||
@ -240,15 +241,4 @@ Most common uses of live view tables include:
|
||||
- Watching for table changes and triggering a follow-up select queries.
|
||||
- Watching metrics from system tables using periodic refresh.
|
||||
|
||||
### Settings {#live-view-settings}
|
||||
|
||||
You can use the following settings to control the behaviour of live views.
|
||||
|
||||
- `allow_experimental_live_view` - enable live views. Default is `0`.
|
||||
- `live_view_heartbeat_interval` - the heartbeat interval in seconds to indicate live query is alive. Default is `15` seconds.
|
||||
- `max_live_view_insert_blocks_before_refresh` - maximum number of inserted blocks after which
|
||||
mergeable blocks are dropped and query is re-executed. Default is `64` inserts.
|
||||
- `temporary_live_view_timeout` - interval after which live view with timeout is deleted. Default is `5` seconds.
|
||||
- `periodic_live_view_refresh` - interval after which periodically refreshed live view is forced to refresh. Default is `60` seconds.
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/sql-reference/statements/create/view/) <!--hide-->
|
||||
|
@ -17,19 +17,21 @@ WATCH [db.]live_view
|
||||
[FORMAT format]
|
||||
```
|
||||
|
||||
The `WATCH` query performs continuous data retrieval from a [live view](./create/view.md#live-view) table. Unless the `LIMIT` clause is specified it provides an infinite stream of query results from a [live view](./create/view.md#live-view).
|
||||
The `WATCH` query performs continuous data retrieval from a [LIVE VIEW](./create/view.md#live-view) table. Unless the `LIMIT` clause is specified it provides an infinite stream of query results from a [LIVE VIEW](./create/view.md#live-view).
|
||||
|
||||
```sql
|
||||
WATCH [db.]live_view
|
||||
WATCH [db.]live_view [EVENTS] [LIMIT n] [FORMAT format]
|
||||
```
|
||||
|
||||
## Virtual columns {#watch-virtual-columns}
|
||||
|
||||
The virtual `_version` column in the query result indicates the current result version.
|
||||
|
||||
**Example:**
|
||||
|
||||
```sql
|
||||
CREATE LIVE VIEW lv WITH REFRESH 5 AS SELECT now();
|
||||
WATCH lv
|
||||
WATCH lv;
|
||||
```
|
||||
|
||||
```bash
|
||||
@ -47,6 +49,8 @@ WATCH lv
|
||||
|
||||
By default, the requested data is returned to the client, while in conjunction with [INSERT INTO](../../sql-reference/statements/insert-into.md) it can be forwarded to a different table.
|
||||
|
||||
**Example:**
|
||||
|
||||
```sql
|
||||
INSERT INTO [db.]table WATCH [db.]live_view ...
|
||||
```
|
||||
@ -56,14 +60,14 @@ INSERT INTO [db.]table WATCH [db.]live_view ...
|
||||
The `EVENTS` clause can be used to obtain a short form of the `WATCH` query where instead of the query result you will just get the latest query result version.
|
||||
|
||||
```sql
|
||||
WATCH [db.]live_view EVENTS
|
||||
WATCH [db.]live_view EVENTS;
|
||||
```
|
||||
|
||||
**Example:**
|
||||
|
||||
```sql
|
||||
CREATE LIVE VIEW lv WITH REFRESH 5 AS SELECT now();
|
||||
WATCH lv EVENTS
|
||||
WATCH lv EVENTS;
|
||||
```
|
||||
|
||||
```bash
|
||||
@ -78,17 +82,17 @@ WATCH lv EVENTS
|
||||
|
||||
## LIMIT Clause {#limit-clause}
|
||||
|
||||
The `LIMIT n` clause species the number of updates the `WATCH` query should wait for before terminating. By default there is no limit on the number of updates and therefore the query will not terminate. The value of `0` indicates that the `WATCH` query should not wait for any new query results and therefore will return immediately once query is evaluated.
|
||||
The `LIMIT n` clause specifies the number of updates the `WATCH` query should wait for before terminating. By default there is no limit on the number of updates and therefore the query will not terminate. The value of `0` indicates that the `WATCH` query should not wait for any new query results and therefore will return immediately once query result is evaluated.
|
||||
|
||||
```sql
|
||||
WATCH [db.]live_view LIMIT 1
|
||||
WATCH [db.]live_view LIMIT 1;
|
||||
```
|
||||
|
||||
**Example:**
|
||||
|
||||
```sql
|
||||
CREATE LIVE VIEW lv WITH REFRESH 5 AS SELECT now();
|
||||
WATCH lv EVENTS LIMIT 1
|
||||
WATCH lv EVENTS LIMIT 1;
|
||||
```
|
||||
|
||||
```bash
|
||||
@ -102,5 +106,4 @@ WATCH lv EVENTS LIMIT 1
|
||||
The `FORMAT` clause works the same way as for the [SELECT](../../sql-reference/statements/select/format.md#format-clause).
|
||||
|
||||
!!! info "Note"
|
||||
The [JSONEachRowWithProgress](../../interfaces/formats/#jsoneachrowwithprogress) format should be used when watching [live view](./create/view.md#live-view) tables over the HTTP interface. The progress messages will be added to the output to keep the long-lived HTTP connection alive until the query result changes. The interval between progress messages is controlled using the [live_view_heartbeat_interval](./create/view.md#live-view-settings) setting.
|
||||
|
||||
The [JSONEachRowWithProgress](../../interfaces/formats.md#jsoneachrowwithprogress) format should be used when watching [LIVE VIEW](./create/view.md#live-view) tables over the HTTP interface. The progress messages will be added to the output to keep the long-lived HTTP connection alive until the query result changes. The interval between progress messages is controlled using the [live_view_heartbeat_interval](./create/view.md#live-view-settings) setting.
|
||||
|
@ -23,7 +23,9 @@ ClickHouse supports the standard grammar for defining windows and window functio
|
||||
| `GROUPS` frame | not supported |
|
||||
| Calculating aggregate functions over a frame (`sum(value) over (order by time)`) | all aggregate functions are supported |
|
||||
| `rank()`, `dense_rank()`, `row_number()` | supported |
|
||||
| `lag/lead(value, offset)` | not supported, replace with `any(value) over (.... rows between <offset> preceding and <offset> preceding)`, or `following` for `lead`|
|
||||
| `lag/lead(value, offset)` | Not supported. Workarounds: |
|
||||
| | 1) replace with `any(value) over (.... rows between <offset> preceding and <offset> preceding)`, or `following` for `lead`|
|
||||
| | 2) use `lagInFrame/leadInFrame`, which are analogous, but respect the window frame. To get behavior identical to `lag/lead`, use `rows between unbounded preceding and unbounded following` |
|
||||
|
||||
## References
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 1
|
||||
toc_title: Nube
|
||||
---
|
||||
|
||||
# Proveedores de servicios en la nube de ClickHouse {#clickhouse-cloud-service-providers}
|
||||
|
||||
!!! info "INFO"
|
||||
Si ha lanzado una nube pública con el servicio ClickHouse administrado, no dude en [abrir una solicitud de extracción](https://github.com/ClickHouse/ClickHouse/edit/master/docs/en/commercial/cloud.md) añadiéndolo a la siguiente lista.
|
||||
|
||||
## Nube de Yandex {#yandex-cloud}
|
||||
|
||||
[Servicio administrado de Yandex para ClickHouse](https://cloud.yandex.com/services/managed-clickhouse?utm_source=referrals&utm_medium=clickhouseofficialsite&utm_campaign=link3) proporciona las siguientes características clave:
|
||||
|
||||
- Servicio ZooKeeper totalmente gestionado para [Replicación de ClickHouse](../engines/table-engines/mergetree-family/replication.md)
|
||||
- Múltiples opciones de tipo de almacenamiento
|
||||
- Réplicas en diferentes zonas de disponibilidad
|
||||
- Cifrado y aislamiento
|
||||
- Mantenimiento automatizado
|
||||
|
||||
{## [Artículo Original](https://clickhouse.tech/docs/en/commercial/cloud/) ##}
|
@ -1,9 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Comercial
|
||||
toc_priority: 70
|
||||
toc_title: Comercial
|
||||
---
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 3
|
||||
toc_title: Apoyo
|
||||
---
|
||||
|
||||
# Proveedores de servicios de soporte comercial ClickHouse {#clickhouse-commercial-support-service-providers}
|
||||
|
||||
!!! info "INFO"
|
||||
Si ha lanzado un servicio de soporte comercial ClickHouse, no dude en [abrir una solicitud de extracción](https://github.com/ClickHouse/ClickHouse/edit/master/docs/en/commercial/support.md) añadiéndolo a la siguiente lista.
|
||||
|
||||
## Altinidad {#altinity}
|
||||
|
||||
Altinity ha ofrecido soporte y servicios empresariales ClickHouse desde 2017. Los clientes de Altinity van desde empresas Fortune 100 hasta startups. Visitar [Más información](https://www.altinity.com/) para más información.
|
||||
|
||||
## Mafiree {#mafiree}
|
||||
|
||||
[Descripción del servicio](http://mafiree.com/clickhouse-analytics-services.php)
|
||||
|
||||
## MinervaDB {#minervadb}
|
||||
|
||||
[Descripción del servicio](https://minervadb.com/index.php/clickhouse-consulting-and-support-by-minervadb/)
|
@ -1,203 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 62
|
||||
toc_title: "Descripci\xF3n general de la arquitectura ClickHouse"
|
||||
---
|
||||
|
||||
# Descripción general de la arquitectura ClickHouse {#overview-of-clickhouse-architecture}
|
||||
|
||||
ClickHouse es un verdadero DBMS orientado a columnas. Los datos se almacenan por columnas y durante la ejecución de matrices (vectores o fragmentos de columnas). Siempre que sea posible, las operaciones se envían en matrices, en lugar de en valores individuales. Se llama “vectorized query execution,” y ayuda a reducir el costo del procesamiento de datos real.
|
||||
|
||||
> Esta idea no es nada nuevo. Se remonta a la `APL` lenguaje de programación y sus descendientes: `A +`, `J`, `K`, y `Q`. La programación de matrices se utiliza en el procesamiento de datos científicos. Tampoco es esta idea algo nuevo en las bases de datos relacionales: por ejemplo, se usa en el `Vectorwise` sistema.
|
||||
|
||||
Existen dos enfoques diferentes para acelerar el procesamiento de consultas: la ejecución de consultas vectorizadas y la generación de código en tiempo de ejecución. Este último elimina toda la indirección y el despacho dinámico. Ninguno de estos enfoques es estrictamente mejor que el otro. La generación de código de tiempo de ejecución puede ser mejor cuando fusiona muchas operaciones, utilizando así las unidades de ejecución de la CPU y la canalización. La ejecución de consultas vectorizadas puede ser menos práctica porque implica vectores temporales que deben escribirse en la memoria caché y leerse. Si los datos temporales no caben en la memoria caché L2, esto se convierte en un problema. Pero la ejecución de consultas vectorizadas utiliza más fácilmente las capacidades SIMD de la CPU. Un [documento de investigación](http://15721.courses.cs.cmu.edu/spring2016/papers/p5-sompolski.pdf) escrito por nuestros amigos muestra que es mejor combinar ambos enfoques. ClickHouse utiliza la ejecución de consultas vectorizadas y tiene un soporte inicial limitado para la generación de código en tiempo de ejecución.
|
||||
|
||||
## Columna {#columns}
|
||||
|
||||
`IColumn` interfaz se utiliza para representar columnas en la memoria (en realidad, fragmentos de columnas). Esta interfaz proporciona métodos auxiliares para la implementación de varios operadores relacionales. Casi todas las operaciones son inmutables: no modifican la columna original, sino que crean una nueva modificada. Por ejemplo, el `IColumn :: filter` método acepta una máscara de bytes de filtro. Se utiliza para el `WHERE` y `HAVING` operadores relacionales. Ejemplos adicionales: el `IColumn :: permute` para apoyar `ORDER BY`, el `IColumn :: cut` para apoyar `LIMIT`.
|
||||
|
||||
Diversos `IColumn` aplicación (`ColumnUInt8`, `ColumnString`, y así sucesivamente) son responsables del diseño de memoria de las columnas. El diseño de memoria suele ser una matriz contigua. Para el tipo entero de columnas, es solo una matriz contigua, como `std :: vector`. Para `String` y `Array` columnas, son dos vectores: uno para todos los elementos de la matriz, colocados contiguamente, y un segundo para los desplazamientos al comienzo de cada matriz. También hay `ColumnConst` que almacena solo un valor en la memoria, pero parece una columna.
|
||||
|
||||
## Campo {#field}
|
||||
|
||||
Sin embargo, también es posible trabajar con valores individuales. Para representar un valor individual, el `Field` se utiliza. `Field` es sólo una unión discriminada de `UInt64`, `Int64`, `Float64`, `String` y `Array`. `IColumn` tiene el `operator[]` para obtener el valor n-ésimo como un `Field` y el `insert` método para agregar un `Field` al final de una columna. Estos métodos no son muy eficientes, ya que requieren tratar con temporal `Field` objetos que representan un valor individual. Hay métodos más eficientes, tales como `insertFrom`, `insertRangeFrom` y así sucesivamente.
|
||||
|
||||
`Field` no tiene suficiente información sobre un tipo de datos específico para una tabla. Por ejemplo, `UInt8`, `UInt16`, `UInt32`, y `UInt64` todos están representados como `UInt64` en una `Field`.
|
||||
|
||||
## Abstracciones con fugas {#leaky-abstractions}
|
||||
|
||||
`IColumn` tiene métodos para transformaciones relacionales comunes de datos, pero no satisfacen todas las necesidades. Por ejemplo, `ColumnUInt64` no tiene un método para calcular la suma de dos columnas, y `ColumnString` no tiene un método para ejecutar una búsqueda de subcadena. Estas innumerables rutinas se implementan fuera de `IColumn`.
|
||||
|
||||
Varias funciones en columnas se pueden implementar de una manera genérica, no eficiente utilizando `IColumn` para extraer `Field` valores, o de una manera especializada utilizando el conocimiento del diseño de la memoria interna de los datos en un `IColumn` aplicación. Se implementa mediante la conversión de funciones a un `IColumn` escriba y trate con la representación interna directamente. Por ejemplo, `ColumnUInt64` tiene el `getData` método que devuelve una referencia a una matriz interna, luego una rutina separada lee o llena esa matriz directamente. Tenemos “leaky abstractions” para permitir especializaciones eficientes de varias rutinas.
|
||||
|
||||
## Tipos de datos {#data_types}
|
||||
|
||||
`IDataType` es responsable de la serialización y deserialización: para leer y escribir fragmentos de columnas o valores individuales en formato binario o de texto. `IDataType` corresponde directamente a los tipos de datos en las tablas. Por ejemplo, hay `DataTypeUInt32`, `DataTypeDateTime`, `DataTypeString` y así sucesivamente.
|
||||
|
||||
`IDataType` y `IColumn` están vagamente relacionados entre sí. Diferentes tipos de datos se pueden representar en la memoria por el mismo `IColumn` aplicación. Por ejemplo, `DataTypeUInt32` y `DataTypeDateTime` están representados por `ColumnUInt32` o `ColumnConstUInt32`. Además, el mismo tipo de datos se puede representar mediante `IColumn` aplicación. Por ejemplo, `DataTypeUInt8` puede ser representado por `ColumnUInt8` o `ColumnConstUInt8`.
|
||||
|
||||
`IDataType` sólo almacena metadatos. Por ejemplo, `DataTypeUInt8` no almacena nada en absoluto (excepto vptr) y `DataTypeFixedString` tiendas solo `N` (el tamaño de las cadenas de tamaño fijo).
|
||||
|
||||
`IDataType` tiene métodos auxiliares para varios formatos de datos. Los ejemplos son métodos para serializar un valor con posibles citas, para serializar un valor para JSON y para serializar un valor como parte del formato XML. No hay correspondencia directa con los formatos de datos. Por ejemplo, los diferentes formatos de datos `Pretty` y `TabSeparated` puede utilizar el mismo `serializeTextEscaped` método de ayuda de la `IDataType` interfaz.
|
||||
|
||||
## Bloque {#block}
|
||||
|
||||
A `Block` es un contenedor que representa un subconjunto (porción) de una tabla en la memoria. Es sólo un conjunto de triples: `(IColumn, IDataType, column name)`. Durante la ejecución de la consulta, los datos son procesados por `Block`s. Si tenemos un `Block`, tenemos datos (en el `IColumn` objeto), tenemos información sobre su tipo (en `IDataType`) que nos dice cómo lidiar con esa columna, y tenemos el nombre de la columna. Podría ser el nombre de columna original de la tabla o algún nombre artificial asignado para obtener resultados temporales de los cálculos.
|
||||
|
||||
Cuando calculamos alguna función sobre columnas en un bloque, agregamos otra columna con su resultado al bloque, y no tocamos columnas para argumentos de la función porque las operaciones son inmutables. Más tarde, las columnas innecesarias se pueden eliminar del bloque, pero no se pueden modificar. Es conveniente para la eliminación de subexpresiones comunes.
|
||||
|
||||
Se crean bloques para cada fragmento de datos procesado. Tenga en cuenta que para el mismo tipo de cálculo, los nombres y tipos de columna siguen siendo los mismos para diferentes bloques y solo cambian los datos de columna. Es mejor dividir los datos del bloque desde el encabezado del bloque porque los tamaños de bloque pequeños tienen una gran sobrecarga de cadenas temporales para copiar shared_ptrs y nombres de columna.
|
||||
|
||||
## Bloquear flujos {#block-streams}
|
||||
|
||||
Los flujos de bloques son para procesar datos. Usamos flujos de bloques para leer datos de algún lugar, realizar transformaciones de datos o escribir datos en algún lugar. `IBlockInputStream` tiene el `read` método para buscar el siguiente bloque mientras esté disponible. `IBlockOutputStream` tiene el `write` método para empujar el bloque en alguna parte.
|
||||
|
||||
Los flujos son responsables de:
|
||||
|
||||
1. Leer o escribir en una mesa. La tabla solo devuelve una secuencia para leer o escribir bloques.
|
||||
2. Implementación de formatos de datos. Por ejemplo, si desea enviar datos a un terminal en `Pretty` formato, crea un flujo de salida de bloque donde presiona bloques y los formatea.
|
||||
3. Realización de transformaciones de datos. Digamos que tienes `IBlockInputStream` y desea crear una secuencia filtrada. Usted crea `FilterBlockInputStream` e inicializarlo con su transmisión. Luego, cuando tiras de un bloque de `FilterBlockInputStream`, extrae un bloque de su flujo, lo filtra y le devuelve el bloque filtrado. Las canalizaciones de ejecución de consultas se representan de esta manera.
|
||||
|
||||
Hay transformaciones más sofisticadas. Por ejemplo, cuando tiras de `AggregatingBlockInputStream`, lee todos los datos de su origen, los agrega y, a continuación, devuelve un flujo de datos agregados para usted. Otro ejemplo: `UnionBlockInputStream` acepta muchas fuentes de entrada en el constructor y también una serie de subprocesos. Lanza múltiples hilos y lee de múltiples fuentes en paralelo.
|
||||
|
||||
> Las secuencias de bloques usan el “pull” enfoque para controlar el flujo: cuando extrae un bloque de la primera secuencia, en consecuencia extrae los bloques requeridos de las secuencias anidadas, y toda la tubería de ejecución funcionará. Ni “pull” ni “push” es la mejor solución, porque el flujo de control está implícito y eso limita la implementación de varias características, como la ejecución simultánea de múltiples consultas (fusionando muchas tuberías). Esta limitación podría superarse con coroutines o simplemente ejecutando hilos adicionales que se esperan el uno al otro. Podemos tener más posibilidades si hacemos explícito el flujo de control: si localizamos la lógica para pasar datos de una unidad de cálculo a otra fuera de esas unidades de cálculo. Lea esto [artículo](http://journal.stuffwithstuff.com/2013/01/13/iteration-inside-and-out/) para más pensamientos.
|
||||
|
||||
Debemos tener en cuenta que la canalización de ejecución de consultas crea datos temporales en cada paso. Tratamos de mantener el tamaño del bloque lo suficientemente pequeño para que los datos temporales se ajusten a la memoria caché de la CPU. Con esa suposición, escribir y leer datos temporales es casi gratis en comparación con otros cálculos. Podríamos considerar una alternativa, que es fusionar muchas operaciones en la tubería. Podría hacer que la tubería sea lo más corta posible y eliminar gran parte de los datos temporales, lo que podría ser una ventaja, pero también tiene inconvenientes. Por ejemplo, una canalización dividida facilita la implementación de almacenamiento en caché de datos intermedios, el robo de datos intermedios de consultas similares que se ejecutan al mismo tiempo y la fusión de canalizaciones para consultas similares.
|
||||
|
||||
## Formato {#formats}
|
||||
|
||||
Los formatos de datos se implementan con flujos de bloques. Hay “presentational” sólo es adecuado para la salida de datos al cliente, tales como `Pretty` formato, que proporciona sólo `IBlockOutputStream`. Y hay formatos de entrada / salida, como `TabSeparated` o `JSONEachRow`.
|
||||
|
||||
También hay secuencias de filas: `IRowInputStream` y `IRowOutputStream`. Permiten pull/push datos por filas individuales, no por bloques. Y solo son necesarios para simplificar la implementación de formatos orientados a filas. Envoltura `BlockInputStreamFromRowInputStream` y `BlockOutputStreamFromRowOutputStream` le permite convertir flujos orientados a filas en flujos regulares orientados a bloques.
|
||||
|
||||
## I/O {#io}
|
||||
|
||||
Para la entrada / salida orientada a bytes, hay `ReadBuffer` y `WriteBuffer` clases abstractas. Se usan en lugar de C ++ `iostream`s. No se preocupe: cada proyecto maduro de C ++ está usando algo más que `iostream`s por buenas razones.
|
||||
|
||||
`ReadBuffer` y `WriteBuffer` son solo un búfer contiguo y un cursor apuntando a la posición en ese búfer. Las implementaciones pueden poseer o no la memoria del búfer. Hay un método virtual para llenar el búfer con los siguientes datos (para `ReadBuffer`) o para vaciar el búfer en algún lugar (para `WriteBuffer`). Los métodos virtuales rara vez se llaman.
|
||||
|
||||
Implementaciones de `ReadBuffer`/`WriteBuffer` se utilizan para trabajar con archivos y descriptores de archivos y sockets de red, para implementar la compresión (`CompressedWriteBuffer` is initialized with another WriteBuffer and performs compression before writing data to it), and for other purposes – the names `ConcatReadBuffer`, `LimitReadBuffer`, y `HashingWriteBuffer` hablar por sí mismos.
|
||||
|
||||
Read / WriteBuffers solo se ocupan de bytes. Hay funciones de `ReadHelpers` y `WriteHelpers` archivos de encabezado para ayudar con el formato de entrada / salida. Por ejemplo, hay ayudantes para escribir un número en formato decimal.
|
||||
|
||||
Veamos qué sucede cuando quieres escribir un conjunto de resultados en `JSON` formato a stdout. Tiene un conjunto de resultados listo para ser recuperado de `IBlockInputStream`. Usted crea `WriteBufferFromFileDescriptor(STDOUT_FILENO)` para escribir bytes en stdout. Usted crea `JSONRowOutputStream`, inicializado con eso `WriteBuffer` para escribir filas en `JSON` a stdout. Usted crea `BlockOutputStreamFromRowOutputStream` encima de él, para representarlo como `IBlockOutputStream`. Entonces usted llama `copyData` para transferir datos desde `IBlockInputStream` a `IBlockOutputStream` y todo funciona. Internamente, `JSONRowOutputStream` escribirá varios delimitadores JSON y llamará al `IDataType::serializeTextJSON` con una referencia a `IColumn` y el número de fila como argumentos. Consecuentemente, `IDataType::serializeTextJSON` llamará a un método de `WriteHelpers.h`: por ejemplo, `writeText` para tipos numéricos y `writeJSONString` para `DataTypeString`.
|
||||
|
||||
## Tabla {#tables}
|
||||
|
||||
El `IStorage` interfaz representa tablas. Las diferentes implementaciones de esa interfaz son diferentes motores de tabla. Los ejemplos son `StorageMergeTree`, `StorageMemory` y así sucesivamente. Las instancias de estas clases son solo tablas.
|
||||
|
||||
Clave `IStorage` son `read` y `write`. También hay `alter`, `rename`, `drop` y así sucesivamente. El `read` método acepta los siguientes argumentos: el conjunto de columnas para leer de una tabla, el `AST` consulta a considerar, y el número deseado de flujos para devolver. Devuelve uno o varios `IBlockInputStream` objetos e información sobre la etapa de procesamiento de datos que se completó dentro de un motor de tablas durante la ejecución de la consulta.
|
||||
|
||||
En la mayoría de los casos, el método de lectura solo es responsable de leer las columnas especificadas de una tabla, no de ningún procesamiento de datos adicional. Todo el procesamiento de datos adicional es realizado por el intérprete de consultas y está fuera de la responsabilidad de `IStorage`.
|
||||
|
||||
Pero hay excepciones notables:
|
||||
|
||||
- La consulta AST se pasa al `read` método, y el motor de tablas puede usarlo para derivar el uso del índice y leer menos datos de una tabla.
|
||||
- A veces, el motor de tablas puede procesar los datos a una etapa específica. Por ejemplo, `StorageDistributed` puede enviar una consulta a servidores remotos, pedirles que procesen datos a una etapa donde se puedan fusionar datos de diferentes servidores remotos y devolver esos datos preprocesados. El intérprete de consultas termina de procesar los datos.
|
||||
|
||||
Tabla `read` método puede devolver múltiples `IBlockInputStream` objetos para permitir el procesamiento de datos en paralelo. Estos flujos de entrada de bloques múltiples pueden leer de una tabla en paralelo. A continuación, puede ajustar estas secuencias con varias transformaciones (como la evaluación de expresiones o el filtrado) que se pueden calcular de forma independiente y crear un `UnionBlockInputStream` encima de ellos, para leer desde múltiples flujos en paralelo.
|
||||
|
||||
También hay `TableFunction`s. Estas son funciones que devuelven un `IStorage` objeto a utilizar en el `FROM` cláusula de una consulta.
|
||||
|
||||
Para tener una idea rápida de cómo implementar su motor de tabla, vea algo simple, como `StorageMemory` o `StorageTinyLog`.
|
||||
|
||||
> Como resultado de la `read` método, `IStorage` devoluciones `QueryProcessingStage` – information about what parts of the query were already calculated inside storage.
|
||||
|
||||
## Analizador {#parsers}
|
||||
|
||||
Un analizador de descenso recursivo escrito a mano analiza una consulta. Por ejemplo, `ParserSelectQuery` simplemente llama recursivamente a los analizadores subyacentes para varias partes de la consulta. Los analizadores crean un `AST`. El `AST` está representado por nodos, que son instancias de `IAST`.
|
||||
|
||||
> Los generadores de analizadores no se utilizan por razones históricas.
|
||||
|
||||
## Interprete {#interpreters}
|
||||
|
||||
Los intérpretes son responsables de crear la canalización de ejecución de consultas `AST`. Hay intérpretes simples, como `InterpreterExistsQuery` y `InterpreterDropQuery` o el más sofisticado `InterpreterSelectQuery`. La canalización de ejecución de consultas es una combinación de flujos de entrada o salida de bloques. Por ejemplo, el resultado de interpretar el `SELECT` la consulta es la `IBlockInputStream` para leer el conjunto de resultados; el resultado de la consulta INSERT es el `IBlockOutputStream` para escribir datos para su inserción, y el resultado de interpretar el `INSERT SELECT` la consulta es la `IBlockInputStream` que devuelve un conjunto de resultados vacío en la primera lectura, pero que copia datos de `SELECT` a `INSERT` al mismo tiempo.
|
||||
|
||||
`InterpreterSelectQuery` utilizar `ExpressionAnalyzer` y `ExpressionActions` maquinaria para el análisis de consultas y transformaciones. Aquí es donde se realizan la mayoría de las optimizaciones de consultas basadas en reglas. `ExpressionAnalyzer` es bastante complicado y debe reescribirse: se deben extraer varias transformaciones de consultas y optimizaciones para separar clases para permitir transformaciones modulares o consultas.
|
||||
|
||||
## Función {#functions}
|
||||
|
||||
Hay funciones ordinarias y funciones agregadas. Para las funciones agregadas, consulte la siguiente sección.
|
||||
|
||||
Ordinary functions don't change the number of rows – they work as if they are processing each row independently. In fact, functions are not called for individual rows, but for `Block`de datos para implementar la ejecución de consultas vectorizadas.
|
||||
|
||||
Hay algunas funciones diversas, como [BlockSize](../sql-reference/functions/other-functions.md#function-blocksize), [rowNumberInBlock](../sql-reference/functions/other-functions.md#function-rownumberinblock), y [runningAccumulate](../sql-reference/functions/other-functions.md#function-runningaccumulate), que explotan el procesamiento de bloques y violan la independencia de las filas.
|
||||
|
||||
ClickHouse tiene una tipificación fuerte, por lo que no hay conversión de tipo implícita. Si una función no admite una combinación específica de tipos, produce una excepción. Pero las funciones pueden funcionar (estar sobrecargadas) para muchas combinaciones diferentes de tipos. Por ejemplo, el `plus` función (para implementar el `+` operador) funciona para cualquier combinación de tipos numéricos: `UInt8` + `Float32`, `UInt16` + `Int8` y así sucesivamente. Además, algunas funciones variadas pueden aceptar cualquier número de argumentos, como el `concat` función.
|
||||
|
||||
Implementar una función puede ser un poco inconveniente porque una función distribuye explícitamente tipos de datos compatibles y `IColumns`. Por ejemplo, el `plus` La función tiene código generado por la creación de instancias de una plantilla de C ++ para cada combinación de tipos numéricos y argumentos izquierdo y derecho constantes o no constantes.
|
||||
|
||||
Es un excelente lugar para implementar la generación de código en tiempo de ejecución para evitar la hinchazón del código de plantilla. Además, permite agregar funciones fusionadas como multiplicar-agregar fusionado o hacer comparaciones múltiples en una iteración de bucle.
|
||||
|
||||
Debido a la ejecución de consultas vectorizadas, las funciones no se cortocircuitan. Por ejemplo, si escribe `WHERE f(x) AND g(y)`, ambos lados se calculan, incluso para las filas, cuando `f(x)` es cero (excepto cuando `f(x)` es una expresión constante cero). Pero si la selectividad del `f(x)` la condición es alta, y el cálculo de `f(x)` es mucho más barato que `g(y)`, es mejor implementar el cálculo de paso múltiple. Primero calcularía `f(x)`, a continuación, filtrar columnas por el resultado, y luego calcular `g(y)` solo para trozos de datos más pequeños y filtrados.
|
||||
|
||||
## Funciones agregadas {#aggregate-functions}
|
||||
|
||||
Las funciones agregadas son funciones con estado. Acumulan valores pasados en algún estado y le permiten obtener resultados de ese estado. Se gestionan con el `IAggregateFunction` interfaz. Los estados pueden ser bastante simples (el estado para `AggregateFunctionCount` es sólo una sola `UInt64` valor) o bastante complejo (el estado de `AggregateFunctionUniqCombined` es una combinación de una matriz lineal, una tabla hash, y un `HyperLogLog` estructura de datos probabilística).
|
||||
|
||||
Los Estados están asignados en `Arena` (un grupo de memoria) para tratar con múltiples estados mientras se ejecuta una alta cardinalidad `GROUP BY` consulta. Los estados pueden tener un constructor y destructor no trivial: por ejemplo, los estados de agregación complicados pueden asignar memoria adicional ellos mismos. Requiere cierta atención a la creación y destrucción de estados y a la adecuada aprobación de su orden de propiedad y destrucción.
|
||||
|
||||
Los estados de agregación se pueden serializar y deserializar para pasar a través de la red durante la ejecución de consultas distribuidas o para escribirlos en el disco donde no hay suficiente RAM. Incluso se pueden almacenar en una tabla con el `DataTypeAggregateFunction` para permitir la agregación incremental de datos.
|
||||
|
||||
> El formato de datos serializados para los estados de función agregados no tiene versiones en este momento. Está bien si los estados agregados solo se almacenan temporalmente. Pero tenemos el `AggregatingMergeTree` motor de tabla para la agregación incremental, y la gente ya lo está utilizando en producción. Es la razón por la que se requiere compatibilidad con versiones anteriores al cambiar el formato serializado para cualquier función agregada en el futuro.
|
||||
|
||||
## Servidor {#server}
|
||||
|
||||
El servidor implementa varias interfaces diferentes:
|
||||
|
||||
- Una interfaz HTTP para cualquier cliente extranjero.
|
||||
- Una interfaz TCP para el cliente nativo de ClickHouse y para la comunicación entre servidores durante la ejecución de consultas distribuidas.
|
||||
- Una interfaz para transferir datos para la replicación.
|
||||
|
||||
Internamente, es solo un servidor multiproceso primitivo sin corutinas ni fibras. Dado que el servidor no está diseñado para procesar una alta tasa de consultas simples, sino para procesar una tasa relativamente baja de consultas complejas, cada uno de ellos puede procesar una gran cantidad de datos para análisis.
|
||||
|
||||
El servidor inicializa el `Context` clase con el entorno necesario para la ejecución de consultas: la lista de bases de datos disponibles, usuarios y derechos de acceso, configuración, clústeres, la lista de procesos, el registro de consultas, etc. Los intérpretes utilizan este entorno.
|
||||
|
||||
Mantenemos una compatibilidad total con versiones anteriores y posteriores para el protocolo TCP del servidor: los clientes antiguos pueden hablar con servidores nuevos y los nuevos clientes pueden hablar con servidores antiguos. Pero no queremos mantenerlo eternamente, y estamos eliminando el soporte para versiones antiguas después de aproximadamente un año.
|
||||
|
||||
!!! note "Nota"
|
||||
Para la mayoría de las aplicaciones externas, recomendamos usar la interfaz HTTP porque es simple y fácil de usar. El protocolo TCP está más estrechamente vinculado a las estructuras de datos internas: utiliza un formato interno para pasar bloques de datos y utiliza marcos personalizados para datos comprimidos. No hemos lanzado una biblioteca C para ese protocolo porque requiere vincular la mayor parte de la base de código ClickHouse, lo cual no es práctico.
|
||||
|
||||
## Ejecución de consultas distribuidas {#distributed-query-execution}
|
||||
|
||||
Los servidores de una configuración de clúster son en su mayoría independientes. Puede crear un `Distributed` en uno o todos los servidores de un clúster. El `Distributed` table does not store data itself – it only provides a “view” a todas las tablas locales en varios nodos de un clúster. Cuando se SELECCIONA desde un `Distributed` tabla, reescribe esa consulta, elige nodos remotos de acuerdo con la configuración de equilibrio de carga y les envía la consulta. El `Distributed` table solicita a los servidores remotos que procesen una consulta hasta una etapa en la que se pueden fusionar resultados intermedios de diferentes servidores. Luego recibe los resultados intermedios y los fusiona. La tabla distribuida intenta distribuir tanto trabajo como sea posible a servidores remotos y no envía muchos datos intermedios a través de la red.
|
||||
|
||||
Las cosas se vuelven más complicadas cuando tiene subconsultas en cláusulas IN o JOIN, y cada una de ellas usa un `Distributed` tabla. Tenemos diferentes estrategias para la ejecución de estas consultas.
|
||||
|
||||
No existe un plan de consulta global para la ejecución de consultas distribuidas. Cada nodo tiene su plan de consulta local para su parte del trabajo. Solo tenemos una ejecución simple de consultas distribuidas de un solo paso: enviamos consultas para nodos remotos y luego fusionamos los resultados. Pero esto no es factible para consultas complicadas con alta cardinalidad GROUP BY o con una gran cantidad de datos temporales para JOIN. En tales casos, necesitamos “reshuffle” datos entre servidores, lo que requiere una coordinación adicional. ClickHouse no admite ese tipo de ejecución de consultas, y tenemos que trabajar en ello.
|
||||
|
||||
## Árbol de fusión {#merge-tree}
|
||||
|
||||
`MergeTree` es una familia de motores de almacenamiento que admite la indexación por clave principal. La clave principal puede ser una tupla arbitraria de columnas o expresiones. Datos en un `MergeTree` se almacena en “parts”. Cada parte almacena los datos en el orden de la clave principal, por lo que la tupla de la clave principal ordena los datos lexicográficamente. Todas las columnas de la tabla se almacenan en `column.bin` archivos en estas partes. Los archivos consisten en bloques comprimidos. Cada bloque suele ser de 64 KB a 1 MB de datos sin comprimir, dependiendo del tamaño del valor promedio. Los bloques constan de valores de columna colocados contiguamente uno tras otro. Los valores de columna están en el mismo orden para cada columna (la clave principal define el orden), por lo que cuando itera por muchas columnas, obtiene valores para las filas correspondientes.
|
||||
|
||||
La clave principal en sí es “sparse”. No aborda cada fila, sino solo algunos rangos de datos. Separado `primary.idx` file tiene el valor de la clave principal para cada fila N-ésima, donde se llama N `index_granularity` (generalmente, N = 8192). Además, para cada columna, tenemos `column.mrk` archivos con “marks,” que son desplazamientos a cada fila N-ésima en el archivo de datos. Cada marca es un par: el desplazamiento en el archivo al comienzo del bloque comprimido y el desplazamiento en el bloque descomprimido al comienzo de los datos. Por lo general, los bloques comprimidos están alineados por marcas, y el desplazamiento en el bloque descomprimido es cero. Datos para `primary.idx` siempre reside en la memoria, y los datos para `column.mrk` archivos se almacena en caché.
|
||||
|
||||
Cuando vamos a leer algo de una parte en `MergeTree` miramos `primary.idx` datos y localice rangos que podrían contener datos solicitados, luego mire `column.mrk` datos y calcular compensaciones para dónde comenzar a leer esos rangos. Debido a la escasez, el exceso de datos puede ser leído. ClickHouse no es adecuado para una gran carga de consultas de puntos simples, porque todo el rango con `index_granularity` se deben leer filas para cada clave, y todo el bloque comprimido debe descomprimirse para cada columna. Hicimos que el índice sea disperso porque debemos poder mantener billones de filas por único servidor sin un consumo de memoria notable para el índice. Además, debido a que la clave principal es escasa, no es única: no puede verificar la existencia de la clave en la tabla en el momento de INSERTAR. Podría tener muchas filas con la misma clave en una tabla.
|
||||
|
||||
Cuando `INSERT` un montón de datos en `MergeTree`, ese grupo está ordenado por orden de clave primaria y forma una nueva parte. Hay subprocesos de fondo que seleccionan periódicamente algunas partes y las fusionan en una sola parte ordenada para mantener el número de partes relativamente bajo. Es por eso que se llama `MergeTree`. Por supuesto, la fusión conduce a “write amplification”. Todas las partes son inmutables: solo se crean y eliminan, pero no se modifican. Cuando se ejecuta SELECT, contiene una instantánea de la tabla (un conjunto de partes). Después de la fusión, también mantenemos las piezas viejas durante algún tiempo para facilitar la recuperación después de la falla, por lo que si vemos que alguna parte fusionada probablemente esté rota, podemos reemplazarla con sus partes de origen.
|
||||
|
||||
`MergeTree` no es un árbol de LSM porque no contiene “memtable” y “log”: inserted data is written directly to the filesystem. This makes it suitable only to INSERT data in batches, not by individual row and not very frequently – about once per second is ok, but a thousand times a second is not. We did it this way for simplicity's sake, and because we are already inserting data in batches in our applications.
|
||||
|
||||
> Las tablas MergeTree solo pueden tener un índice (primario): no hay índices secundarios. Sería bueno permitir múltiples representaciones físicas bajo una tabla lógica, por ejemplo, para almacenar datos en más de un orden físico o incluso para permitir representaciones con datos preagregados junto con datos originales.
|
||||
|
||||
Hay motores MergeTree que están haciendo un trabajo adicional durante las fusiones en segundo plano. Los ejemplos son `CollapsingMergeTree` y `AggregatingMergeTree`. Esto podría tratarse como soporte especial para actualizaciones. Tenga en cuenta que estas no son actualizaciones reales porque los usuarios generalmente no tienen control sobre el tiempo en que se ejecutan las fusiones en segundo plano y los datos en un `MergeTree` casi siempre se almacena en más de una parte, no en forma completamente fusionada.
|
||||
|
||||
## Replicación {#replication}
|
||||
|
||||
La replicación en ClickHouse se puede configurar por tabla. Podría tener algunas tablas replicadas y otras no replicadas en el mismo servidor. También puede tener tablas replicadas de diferentes maneras, como una tabla con replicación de dos factores y otra con replicación de tres factores.
|
||||
|
||||
La replicación se implementa en el `ReplicatedMergeTree` motor de almacenamiento. El camino en `ZooKeeper` se especifica como un parámetro para el motor de almacenamiento. Todas las tablas con la misma ruta en `ZooKeeper` se convierten en réplicas entre sí: sincronizan sus datos y mantienen la coherencia. Las réplicas se pueden agregar y eliminar dinámicamente simplemente creando o soltando una tabla.
|
||||
|
||||
La replicación utiliza un esquema multi-maestro asíncrono. Puede insertar datos en cualquier réplica que tenga una sesión con `ZooKeeper`, y los datos se replican en todas las demás réplicas de forma asíncrona. Como ClickHouse no admite UPDATE, la replicación está libre de conflictos. Como no hay reconocimiento de quórum de inserciones, los datos recién insertados pueden perderse si un nodo falla.
|
||||
|
||||
Los metadatos para la replicación se almacenan en ZooKeeper. Hay un registro de replicación que enumera las acciones que se deben realizar. Las acciones son: obtener parte; fusionar partes; soltar una partición, etc. Cada réplica copia el registro de replicación en su cola y, a continuación, ejecuta las acciones desde la cola. Por ejemplo, en la inserción, el “get the part” la acción se crea en el registro y cada réplica descarga esa parte. Las fusiones se coordinan entre réplicas para obtener resultados idénticos en bytes. Todas las piezas se combinan de la misma manera en todas las réplicas. Se logra eligiendo una réplica como líder, y esa réplica inicia fusiones y escrituras “merge parts” acciones al registro.
|
||||
|
||||
La replicación es física: solo las partes comprimidas se transfieren entre nodos, no consultas. Las fusiones se procesan en cada réplica de forma independiente en la mayoría de los casos para reducir los costos de red al evitar la amplificación de la red. Las piezas combinadas grandes se envían a través de la red solo en casos de retraso de replicación significativo.
|
||||
|
||||
Además, cada réplica almacena su estado en ZooKeeper como el conjunto de piezas y sus sumas de comprobación. Cuando el estado en el sistema de archivos local difiere del estado de referencia en ZooKeeper, la réplica restaura su coherencia descargando partes faltantes y rotas de otras réplicas. Cuando hay algunos datos inesperados o rotos en el sistema de archivos local, ClickHouse no los elimina, sino que los mueve a un directorio separado y los olvida.
|
||||
|
||||
!!! note "Nota"
|
||||
El clúster ClickHouse consta de fragmentos independientes y cada fragmento consta de réplicas. El clúster es **no elástico**, por lo tanto, después de agregar un nuevo fragmento, los datos no se reequilibran automáticamente entre fragmentos. En su lugar, se supone que la carga del clúster debe ajustarse para que sea desigual. Esta implementación le da más control, y está bien para clústeres relativamente pequeños, como decenas de nodos. Pero para los clústeres con cientos de nodos que estamos utilizando en producción, este enfoque se convierte en un inconveniente significativo. Debemos implementar un motor de tablas que abarque todo el clúster con regiones replicadas dinámicamente que puedan dividirse y equilibrarse entre clústeres automáticamente.
|
||||
|
||||
{## [Artículo Original](https://clickhouse.tech/docs/en/development/architecture/) ##}
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 63
|
||||
toc_title: "Buscar c\xF3digo fuente"
|
||||
---
|
||||
|
||||
# Examinar el código fuente de ClickHouse {#browse-clickhouse-source-code}
|
||||
|
||||
Usted puede utilizar **Woboq** navegador de código en línea disponible [aqui](https://clickhouse.tech/codebrowser/html_report/ClickHouse/src/index.html). Proporciona navegación de código y resaltado semántico, búsqueda e indexación. La instantánea de código se actualiza diariamente.
|
||||
|
||||
Además, puede navegar por las fuentes en [GitHub](https://github.com/ClickHouse/ClickHouse) como de costumbre.
|
||||
|
||||
Si está interesado en qué IDE usar, recomendamos CLion, QT Creator, VS Code y KDevelop (con advertencias). Puedes usar cualquier IDE favorito. Vim y Emacs también cuentan.
|
@ -1,43 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 67
|
||||
toc_title: "C\xF3mo construir ClickHouse en Linux para AARCH64 (ARM64)"
|
||||
---
|
||||
|
||||
# Cómo construir ClickHouse en Linux para la arquitectura AARCH64 (ARM64) {#how-to-build-clickhouse-on-linux-for-aarch64-arm64-architecture}
|
||||
|
||||
Esto es para el caso cuando tiene una máquina Linux y desea usarla para compilar `clickhouse` binario que se ejecutará en otra máquina Linux con arquitectura de CPU AARCH64. Esto está destinado a las comprobaciones de integración continua que se ejecutan en servidores Linux.
|
||||
|
||||
La compilación cruzada para AARCH64 se basa en el [Instrucciones de construcción](build.md), seguirlos primero.
|
||||
|
||||
# Instalar Clang-8 {#install-clang-8}
|
||||
|
||||
Siga las instrucciones de https://apt.llvm.org/ para la configuración de Ubuntu o Debian.
|
||||
Por ejemplo, en Ubuntu Bionic puede usar los siguientes comandos:
|
||||
|
||||
``` bash
|
||||
echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main" | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-8
|
||||
```
|
||||
|
||||
# Instalar conjunto de herramientas de compilación cruzada {#install-cross-compilation-toolset}
|
||||
|
||||
``` bash
|
||||
cd ClickHouse
|
||||
mkdir -p build-aarch64/cmake/toolchain/linux-aarch64
|
||||
wget 'https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz?revision=2e88a73f-d233-4f96-b1f4-d8b36e9bb0b9&la=en' -O gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz
|
||||
tar xJf gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz -C build-aarch64/cmake/toolchain/linux-aarch64 --strip-components=1
|
||||
```
|
||||
|
||||
# Construir ClickHouse {#build-clickhouse}
|
||||
|
||||
``` bash
|
||||
cd ClickHouse
|
||||
mkdir build-arm64
|
||||
CC=clang-8 CXX=clang++-8 cmake . -Bbuild-arm64 -DCMAKE_TOOLCHAIN_FILE=cmake/linux/toolchain-aarch64.cmake
|
||||
ninja -C build-arm64
|
||||
```
|
||||
|
||||
El binario resultante se ejecutará solo en Linux con la arquitectura de CPU AARCH64.
|
@ -1,64 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 66
|
||||
toc_title: "C\xF3mo construir ClickHouse en Linux para Mac OS X"
|
||||
---
|
||||
|
||||
# Cómo construir ClickHouse en Linux para Mac OS X {#how-to-build-clickhouse-on-linux-for-mac-os-x}
|
||||
|
||||
Esto es para el caso cuando tiene una máquina Linux y desea usarla para compilar `clickhouse` Esto está destinado a las comprobaciones de integración continuas que se ejecutan en servidores Linux. Si desea crear ClickHouse directamente en Mac OS X, continúe con [otra instrucción](build-osx.md).
|
||||
|
||||
La compilación cruzada para Mac OS X se basa en el [Instrucciones de construcción](build.md), seguirlos primero.
|
||||
|
||||
# Instalar Clang-8 {#install-clang-8}
|
||||
|
||||
Siga las instrucciones de https://apt.llvm.org/ para la configuración de Ubuntu o Debian.
|
||||
Por ejemplo, los comandos para Bionic son como:
|
||||
|
||||
``` bash
|
||||
sudo echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main" >> /etc/apt/sources.list
|
||||
sudo apt-get install clang-8
|
||||
```
|
||||
|
||||
# Instalar conjunto de herramientas de compilación cruzada {#install-cross-compilation-toolset}
|
||||
|
||||
Recordemos la ruta donde instalamos `cctools` como ${CCTOOLS}
|
||||
|
||||
``` bash
|
||||
mkdir ${CCTOOLS}
|
||||
|
||||
git clone https://github.com/tpoechtrager/apple-libtapi.git
|
||||
cd apple-libtapi
|
||||
INSTALLPREFIX=${CCTOOLS} ./build.sh
|
||||
./install.sh
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/tpoechtrager/cctools-port.git
|
||||
cd cctools-port/cctools
|
||||
./configure --prefix=${CCTOOLS} --with-libtapi=${CCTOOLS} --target=x86_64-apple-darwin
|
||||
make install
|
||||
```
|
||||
|
||||
Además, necesitamos descargar macOS X SDK en el árbol de trabajo.
|
||||
|
||||
``` bash
|
||||
cd ClickHouse
|
||||
wget 'https://github.com/phracker/MacOSX-SDKs/releases/download/10.15/MacOSX10.15.sdk.tar.xz'
|
||||
mkdir -p build-darwin/cmake/toolchain/darwin-x86_64
|
||||
tar xJf MacOSX10.15.sdk.tar.xz -C build-darwin/cmake/toolchain/darwin-x86_64 --strip-components=1
|
||||
```
|
||||
|
||||
# Construir ClickHouse {#build-clickhouse}
|
||||
|
||||
``` bash
|
||||
cd ClickHouse
|
||||
mkdir build-osx
|
||||
CC=clang-8 CXX=clang++-8 cmake . -Bbuild-osx -DCMAKE_TOOLCHAIN_FILE=cmake/darwin/toolchain-x86_64.cmake \
|
||||
-DCMAKE_AR:FILEPATH=${CCTOOLS}/bin/x86_64-apple-darwin-ar \
|
||||
-DCMAKE_RANLIB:FILEPATH=${CCTOOLS}/bin/x86_64-apple-darwin-ranlib \
|
||||
-DLINKER_NAME=${CCTOOLS}/bin/x86_64-apple-darwin-ld
|
||||
ninja -C build-osx
|
||||
```
|
||||
|
||||
El binario resultante tendrá un formato ejecutable Mach-O y no se puede ejecutar en Linux.
|
@ -1,93 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 65
|
||||
toc_title: "C\xF3mo crear ClickHouse en Mac OS X"
|
||||
---
|
||||
|
||||
# Cómo crear ClickHouse en Mac OS X {#how-to-build-clickhouse-on-mac-os-x}
|
||||
|
||||
Build debería funcionar en Mac OS X 10.15 (Catalina)
|
||||
|
||||
## Instalar Homebrew {#install-homebrew}
|
||||
|
||||
``` bash
|
||||
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
```
|
||||
|
||||
## Instalar compiladores, herramientas y bibliotecas necesarios {#install-required-compilers-tools-and-libraries}
|
||||
|
||||
``` bash
|
||||
$ brew install cmake ninja libtool gettext
|
||||
```
|
||||
|
||||
## Fuentes de ClickHouse de pago {#checkout-clickhouse-sources}
|
||||
|
||||
``` bash
|
||||
$ git clone --recursive git@github.com:ClickHouse/ClickHouse.git
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
``` bash
|
||||
$ git clone --recursive https://github.com/ClickHouse/ClickHouse.git
|
||||
|
||||
$ cd ClickHouse
|
||||
```
|
||||
|
||||
## Construir ClickHouse {#build-clickhouse}
|
||||
|
||||
``` bash
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake .. -DCMAKE_CXX_COMPILER=`which clang++` -DCMAKE_C_COMPILER=`which clang`
|
||||
$ ninja
|
||||
$ cd ..
|
||||
```
|
||||
|
||||
## Advertencia {#caveats}
|
||||
|
||||
Si tiene la intención de ejecutar clickhouse-server, asegúrese de aumentar la variable maxfiles del sistema.
|
||||
|
||||
!!! info "Nota"
|
||||
Tendrás que usar sudo.
|
||||
|
||||
Para ello, cree el siguiente archivo:
|
||||
|
||||
/Library/LaunchDaemons/limit.maxfiles.lista:
|
||||
|
||||
``` xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>limit.maxfiles</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>launchctl</string>
|
||||
<string>limit</string>
|
||||
<string>maxfiles</string>
|
||||
<string>524288</string>
|
||||
<string>524288</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>ServiceIPC</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
Ejecute el siguiente comando:
|
||||
|
||||
``` bash
|
||||
$ sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
|
||||
```
|
||||
|
||||
Reiniciar.
|
||||
|
||||
Para verificar si está funcionando, puede usar `ulimit -n` comando.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/development/build_osx/) <!--hide-->
|
@ -1,141 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 64
|
||||
toc_title: "C\xF3mo crear ClickHouse en Linux"
|
||||
---
|
||||
|
||||
# Cómo construir ClickHouse para el desarrollo {#how-to-build-clickhouse-for-development}
|
||||
|
||||
El siguiente tutorial se basa en el sistema Ubuntu Linux.
|
||||
Con los cambios apropiados, también debería funcionar en cualquier otra distribución de Linux.
|
||||
Plataformas compatibles: x86_64 y AArch64. El soporte para Power9 es experimental.
|
||||
|
||||
## Instalar Git, CMake, Python y Ninja {#install-git-cmake-python-and-ninja}
|
||||
|
||||
``` bash
|
||||
$ sudo apt-get install git cmake python ninja-build
|
||||
```
|
||||
|
||||
O cmake3 en lugar de cmake en sistemas más antiguos.
|
||||
|
||||
## Instalar GCC 10 {#install-gcc-10}
|
||||
|
||||
Hay varias formas de hacer esto.
|
||||
|
||||
### Instalar desde un paquete PPA {#install-from-a-ppa-package}
|
||||
|
||||
``` bash
|
||||
$ sudo apt-get install software-properties-common
|
||||
$ sudo apt-add-repository ppa:ubuntu-toolchain-r/test
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install gcc-10 g++-10
|
||||
```
|
||||
|
||||
### Instalar desde fuentes {#install-from-sources}
|
||||
|
||||
Mira [Sistema abierto.](https://github.com/ClickHouse/ClickHouse/blob/master/utils/ci/build-gcc-from-sources.sh)
|
||||
|
||||
## Usar GCC 10 para compilaciones {#use-gcc-10-for-builds}
|
||||
|
||||
``` bash
|
||||
$ export CC=gcc-10
|
||||
$ export CXX=g++-10
|
||||
```
|
||||
|
||||
## Fuentes de ClickHouse de pago {#checkout-clickhouse-sources}
|
||||
|
||||
``` bash
|
||||
$ git clone --recursive git@github.com:ClickHouse/ClickHouse.git
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
``` bash
|
||||
$ git clone --recursive https://github.com/ClickHouse/ClickHouse.git
|
||||
```
|
||||
|
||||
## Construir ClickHouse {#build-clickhouse}
|
||||
|
||||
``` bash
|
||||
$ cd ClickHouse
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake ..
|
||||
$ ninja
|
||||
$ cd ..
|
||||
```
|
||||
|
||||
Para crear un ejecutable, ejecute `ninja clickhouse`.
|
||||
Esto creará el `programs/clickhouse` ejecutable, que se puede usar con `client` o `server` argumento.
|
||||
|
||||
# Cómo construir ClickHouse en cualquier Linux {#how-to-build-clickhouse-on-any-linux}
|
||||
|
||||
La compilación requiere los siguientes componentes:
|
||||
|
||||
- Git (se usa solo para verificar las fuentes, no es necesario para la compilación)
|
||||
- CMake 3.10 o más reciente
|
||||
- Ninja (recomendado) o Hacer
|
||||
- Compilador de C ++: gcc 10 o clang 8 o más reciente
|
||||
- Enlazador: lld u oro (el clásico GNU ld no funcionará)
|
||||
- Python (solo se usa dentro de la compilación LLVM y es opcional)
|
||||
|
||||
Si todos los componentes están instalados, puede compilar de la misma manera que los pasos anteriores.
|
||||
|
||||
Ejemplo para Ubuntu Eoan:
|
||||
|
||||
sudo apt update
|
||||
sudo apt install git cmake ninja-build g++ python
|
||||
git clone --recursive https://github.com/ClickHouse/ClickHouse.git
|
||||
mkdir build && cd build
|
||||
cmake ../ClickHouse
|
||||
ninja
|
||||
|
||||
Ejemplo de OpenSUSE Tumbleweed:
|
||||
|
||||
sudo zypper install git cmake ninja gcc-c++ python lld
|
||||
git clone --recursive https://github.com/ClickHouse/ClickHouse.git
|
||||
mkdir build && cd build
|
||||
cmake ../ClickHouse
|
||||
ninja
|
||||
|
||||
Ejemplo de Fedora Rawhide:
|
||||
|
||||
sudo yum update
|
||||
yum --nogpg install git cmake make gcc-c++ python3
|
||||
git clone --recursive https://github.com/ClickHouse/ClickHouse.git
|
||||
mkdir build && cd build
|
||||
cmake ../ClickHouse
|
||||
make -j $(nproc)
|
||||
|
||||
# No tienes que construir ClickHouse {#you-dont-have-to-build-clickhouse}
|
||||
|
||||
ClickHouse está disponible en binarios y paquetes preconstruidos. Los binarios son portátiles y se pueden ejecutar en cualquier tipo de Linux.
|
||||
|
||||
Están diseñados para lanzamientos estables, preestablecidos y de prueba, siempre que para cada compromiso con el maestro y para cada solicitud de extracción.
|
||||
|
||||
Para encontrar la construcción más fresca de `master`, ir a [se compromete página](https://github.com/ClickHouse/ClickHouse/commits/master), haga clic en la primera marca de verificación verde o cruz roja cerca de confirmar, y haga clic en “Details” enlace justo después “ClickHouse Build Check”.
|
||||
|
||||
# Cómo construir el paquete Debian ClickHouse {#how-to-build-clickhouse-debian-package}
|
||||
|
||||
## Instalar Git y Pbuilder {#install-git-and-pbuilder}
|
||||
|
||||
``` bash
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install git python pbuilder debhelper lsb-release fakeroot sudo debian-archive-keyring debian-keyring
|
||||
```
|
||||
|
||||
## Fuentes de ClickHouse de pago {#checkout-clickhouse-sources-1}
|
||||
|
||||
``` bash
|
||||
$ git clone --recursive --branch master https://github.com/ClickHouse/ClickHouse.git
|
||||
$ cd ClickHouse
|
||||
```
|
||||
|
||||
## Ejecutar secuencia de comandos de lanzamiento {#run-release-script}
|
||||
|
||||
``` bash
|
||||
$ ./release
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/development/build/) <!--hide-->
|
@ -1,41 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 70
|
||||
toc_title: Bibliotecas de terceros utilizadas
|
||||
---
|
||||
|
||||
# Bibliotecas de terceros utilizadas {#third-party-libraries-used}
|
||||
|
||||
| Biblioteca | Licencia |
|
||||
|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| base64 | [Licencia BSD de 2 cláusulas](https://github.com/aklomp/base64/blob/a27c565d1b6c676beaf297fe503c4518185666f7/LICENSE) |
|
||||
| impulsar | [Licencia de software Boost 1.0](https://github.com/ClickHouse-Extras/boost-extra/blob/6883b40449f378019aec792f9983ce3afc7ff16e/LICENSE_1_0.txt) |
|
||||
| Bienvenido | [MIT](https://github.com/google/brotli/blob/master/LICENSE) |
|
||||
| capnproto | [MIT](https://github.com/capnproto/capnproto/blob/master/LICENSE) |
|
||||
| Cctz | [Licencia Apache 2.0](https://github.com/google/cctz/blob/4f9776a310f4952454636363def82c2bf6641d5f/LICENSE.txt) |
|
||||
| doble conversión | [Licencia de 3 cláusulas BSD](https://github.com/google/double-conversion/blob/cf2f0f3d547dc73b4612028a155b80536902ba02/LICENSE) |
|
||||
| FastMemcpy | [MIT](https://github.com/ClickHouse/ClickHouse/blob/master/libs/libmemcpy/impl/LICENSE) |
|
||||
| Más información | [Licencia de 3 cláusulas BSD](https://github.com/google/googletest/blob/master/LICENSE) |
|
||||
| H3 | [Licencia Apache 2.0](https://github.com/uber/h3/blob/master/LICENSE) |
|
||||
| hyperscan | [Licencia de 3 cláusulas BSD](https://github.com/intel/hyperscan/blob/master/LICENSE) |
|
||||
| libcxxabi | [BSD + MIT](https://github.com/ClickHouse/ClickHouse/blob/master/libs/libglibc-compatibility/libcxxabi/LICENSE.TXT) |
|
||||
| libdivide | [Licencia Zlib](https://github.com/ClickHouse/ClickHouse/blob/master/contrib/libdivide/LICENSE.txt) |
|
||||
| libgsasl | [Información adicional](https://github.com/ClickHouse-Extras/libgsasl/blob/3b8948a4042e34fb00b4fb987535dc9e02e39040/LICENSE) |
|
||||
| libhdfs3 | [Licencia Apache 2.0](https://github.com/ClickHouse-Extras/libhdfs3/blob/bd6505cbb0c130b0db695305b9a38546fa880e5a/LICENSE.txt) |
|
||||
| libmetrohash | [Licencia Apache 2.0](https://github.com/ClickHouse/ClickHouse/blob/master/contrib/libmetrohash/LICENSE) |
|
||||
| libpcg-al azar | [Licencia Apache 2.0](https://github.com/ClickHouse/ClickHouse/blob/master/contrib/libpcg-random/LICENSE-APACHE.txt) |
|
||||
| Libressl | [Licencia OpenSSL](https://github.com/ClickHouse-Extras/ssl/blob/master/COPYING) |
|
||||
| Librdkafka | [Licencia BSD de 2 cláusulas](https://github.com/edenhill/librdkafka/blob/363dcad5a23dc29381cc626620e68ae418b3af19/LICENSE) |
|
||||
| libwidechar_width | [CC0 1.0 Universal](https://github.com/ClickHouse/ClickHouse/blob/master/libs/libwidechar_width/LICENSE) |
|
||||
| llvm | [Licencia de 3 cláusulas BSD](https://github.com/ClickHouse-Extras/llvm/blob/163def217817c90fb982a6daf384744d8472b92b/llvm/LICENSE.TXT) |
|
||||
| lz4 | [Licencia BSD de 2 cláusulas](https://github.com/lz4/lz4/blob/c10863b98e1503af90616ae99725ecd120265dfb/LICENSE) |
|
||||
| mariadb-conector-c | [Información adicional](https://github.com/ClickHouse-Extras/mariadb-connector-c/blob/3.1/COPYING.LIB) |
|
||||
| murmurhash | [Dominio público](https://github.com/ClickHouse/ClickHouse/blob/master/contrib/murmurhash/LICENSE) |
|
||||
| pdqsort | [Licencia Zlib](https://github.com/ClickHouse/ClickHouse/blob/master/contrib/pdqsort/license.txt) |
|
||||
| Poco | [Boost Software License - Versión 1.0](https://github.com/ClickHouse-Extras/poco/blob/fe5505e56c27b6ecb0dcbc40c49dc2caf4e9637f/LICENSE) |
|
||||
| protobuf | [Licencia de 3 cláusulas BSD](https://github.com/ClickHouse-Extras/protobuf/blob/12735370922a35f03999afff478e1c6d7aa917a4/LICENSE) |
|
||||
| Re2 | [Licencia de 3 cláusulas BSD](https://github.com/google/re2/blob/7cf8b88e8f70f97fd4926b56aa87e7f53b2717e0/LICENSE) |
|
||||
| UnixODBC | [Información adicional](https://github.com/ClickHouse-Extras/UnixODBC/tree/b0ad30f7f6289c12b76f04bfb9d466374bb32168) |
|
||||
| Sistema abierto. | [Licencia Zlib](https://github.com/ClickHouse-Extras/zlib-ng/blob/develop/LICENSE.md) |
|
||||
| zstd | [Licencia de 3 cláusulas BSD](https://github.com/facebook/zstd/blob/dev/LICENSE) |
|
@ -1,287 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 61
|
||||
toc_title: "La instrucci\xF3n para desarrolladores de ClickHouse para principiantes"
|
||||
---
|
||||
|
||||
La construcción de ClickHouse es compatible con Linux, FreeBSD y Mac OS X.
|
||||
|
||||
# Si utiliza Windows {#if-you-use-windows}
|
||||
|
||||
Si usa Windows, necesita crear una máquina virtual con Ubuntu. Para comenzar a trabajar con una máquina virtual, instale VirtualBox. Puede descargar Ubuntu desde el sitio web: https://www.ubuntu.com/#download. Por favor, cree una máquina virtual a partir de la imagen descargada (debe reservar al menos 4 GB de RAM para ello). Para ejecutar un terminal de línea de comandos en Ubuntu, busque un programa que contenga la palabra “terminal” en su nombre (gnome-terminal, konsole etc.) o simplemente presione Ctrl + Alt + T.
|
||||
|
||||
# Si utiliza un sistema de 32 bits {#if-you-use-a-32-bit-system}
|
||||
|
||||
ClickHouse no puede funcionar ni construir en un sistema de 32 bits. Debe adquirir acceso a un sistema de 64 bits y puede continuar leyendo.
|
||||
|
||||
# Creación de un repositorio en GitHub {#creating-a-repository-on-github}
|
||||
|
||||
Para comenzar a trabajar con el repositorio de ClickHouse, necesitará una cuenta de GitHub.
|
||||
|
||||
Probablemente ya tenga uno, pero si no lo hace, regístrese en https://github.com . En caso de que no tenga claves SSH, debe generarlas y luego cargarlas en GitHub. Es necesario para enviar a través de sus parches. También es posible usar las mismas claves SSH que usa con cualquier otro servidor SSH, probablemente ya las tenga.
|
||||
|
||||
Cree una bifurcación del repositorio ClickHouse. Para hacerlo por favor haga clic en el “fork” botón en la esquina superior derecha en https://github.com/ClickHouse/ClickHouse . Se bifurcará su propia copia de ClickHouse/ClickHouse a su cuenta.
|
||||
|
||||
El proceso de desarrollo consiste en comprometer primero los cambios previstos en su bifurcación de ClickHouse y luego crear un “pull request” para que estos cambios sean aceptados en el repositorio principal (ClickHouse / ClickHouse).
|
||||
|
||||
Para trabajar con repositorios git, instale `git`.
|
||||
|
||||
Para hacer eso en Ubuntu, ejecutaría en la terminal de línea de comandos:
|
||||
|
||||
sudo apt update
|
||||
sudo apt install git
|
||||
|
||||
Puede encontrar un breve manual sobre el uso de Git aquí: https://education.github.com/git-cheat-sheet-education.pdf .
|
||||
Para obtener un manual detallado sobre Git, consulte https://git-scm.com/book/en/v2 .
|
||||
|
||||
# Clonación de un repositorio en su máquina de desarrollo {#cloning-a-repository-to-your-development-machine}
|
||||
|
||||
A continuación, debe descargar los archivos fuente en su máquina de trabajo. Esto se llama “to clone a repository” porque crea una copia local del repositorio en su máquina de trabajo.
|
||||
|
||||
En el terminal de línea de comandos, ejecute:
|
||||
|
||||
git clone --recursive git@github.com:your_github_username/ClickHouse.git
|
||||
cd ClickHouse
|
||||
|
||||
Nota: por favor, sustituye *your_github_username* con lo que es apropiado!
|
||||
|
||||
Este comando creará un directorio `ClickHouse` que contiene la copia de trabajo del proyecto.
|
||||
|
||||
Es importante que la ruta al directorio de trabajo no contenga espacios en blanco, ya que puede ocasionar problemas con la ejecución del sistema de compilación.
|
||||
|
||||
Tenga en cuenta que el repositorio ClickHouse utiliza `submodules`. That is what the references to additional repositories are called (i.e. external libraries on which the project depends). It means that when cloning the repository you need to specify the `--recursive` como en el ejemplo anterior. Si el repositorio se ha clonado sin submódulos, para descargarlos debe ejecutar lo siguiente:
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
Puede verificar el estado con el comando: `git submodule status`.
|
||||
|
||||
Si recibe el siguiente mensaje de error:
|
||||
|
||||
Permission denied (publickey).
|
||||
fatal: Could not read from remote repository.
|
||||
|
||||
Please make sure you have the correct access rights
|
||||
and the repository exists.
|
||||
|
||||
Por lo general, significa que faltan las claves SSH para conectarse a GitHub. Estas teclas se encuentran normalmente en `~/.ssh`. Para que las claves SSH sean aceptadas, debe cargarlas en la sección de configuración de la interfaz de usuario de GitHub.
|
||||
|
||||
También puede clonar el repositorio a través del protocolo https:
|
||||
|
||||
git clone https://github.com/ClickHouse/ClickHouse.git
|
||||
|
||||
Sin embargo, esto no le permitirá enviar los cambios al servidor. Aún puede usarlo temporalmente y agregar las claves SSH más tarde reemplazando la dirección remota del repositorio con `git remote` comando.
|
||||
|
||||
También puede agregar la dirección original del repositorio de ClickHouse a su repositorio local para extraer actualizaciones desde allí:
|
||||
|
||||
git remote add upstream git@github.com:ClickHouse/ClickHouse.git
|
||||
|
||||
Después de ejecutar con éxito este comando, podrá extraer actualizaciones del repositorio principal de ClickHouse ejecutando `git pull upstream master`.
|
||||
|
||||
## Trabajar con submódulos {#working-with-submodules}
|
||||
|
||||
Trabajar con submódulos en git podría ser doloroso. Los siguientes comandos ayudarán a administrarlo:
|
||||
|
||||
# ! each command accepts --recursive
|
||||
# Update remote URLs for submodules. Barely rare case
|
||||
git submodule sync
|
||||
# Add new submodules
|
||||
git submodule init
|
||||
# Update existing submodules to the current state
|
||||
git submodule update
|
||||
# Two last commands could be merged together
|
||||
git submodule update --init
|
||||
|
||||
Los siguientes comandos le ayudarían a restablecer todos los submódulos al estado inicial (!¡ADVERTENCIA! - cualquier cambio en el interior será eliminado):
|
||||
|
||||
# Synchronizes submodules' remote URL with .gitmodules
|
||||
git submodule sync --recursive
|
||||
# Update the registered submodules with initialize not yet initialized
|
||||
git submodule update --init --recursive
|
||||
# Reset all changes done after HEAD
|
||||
git submodule foreach git reset --hard
|
||||
# Clean files from .gitignore
|
||||
git submodule foreach git clean -xfd
|
||||
# Repeat last 4 commands for all submodule
|
||||
git submodule foreach git submodule sync --recursive
|
||||
git submodule foreach git submodule update --init --recursive
|
||||
git submodule foreach git submodule foreach git reset --hard
|
||||
git submodule foreach git submodule foreach git clean -xfd
|
||||
|
||||
# Sistema de construcción {#build-system}
|
||||
|
||||
ClickHouse utiliza CMake y Ninja para la construcción.
|
||||
|
||||
CMake - un sistema de meta-construcción que puede generar archivos Ninja (tareas de construcción).
|
||||
Ninja: un sistema de compilación más pequeño con un enfoque en la velocidad utilizada para ejecutar esas tareas generadas por cmake.
|
||||
|
||||
Para instalar en Ubuntu, Debian o Mint run `sudo apt install cmake ninja-build`.
|
||||
|
||||
En CentOS, RedHat se ejecuta `sudo yum install cmake ninja-build`.
|
||||
|
||||
Si usa Arch o Gentoo, probablemente lo sepa usted mismo cómo instalar CMake.
|
||||
|
||||
Para instalar CMake y Ninja en Mac OS X, primero instale Homebrew y luego instale todo lo demás a través de brew:
|
||||
|
||||
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
brew install cmake ninja
|
||||
|
||||
A continuación, verifique la versión de CMake: `cmake --version`. Si está por debajo de 3.3, debe instalar una versión más reciente desde el sitio web: https://cmake.org/download/.
|
||||
|
||||
# Bibliotecas externas opcionales {#optional-external-libraries}
|
||||
|
||||
ClickHouse utiliza varias bibliotecas externas para la construcción. Todos ellos no necesitan ser instalados por separado, ya que se construyen junto con ClickHouse a partir de las fuentes ubicadas en los submódulos. Puede consultar la lista en `contrib`.
|
||||
|
||||
# Compilador de C ++ {#c-compiler}
|
||||
|
||||
Los compiladores GCC a partir de la versión 10 y Clang versión 8 o superior son compatibles para construir ClickHouse.
|
||||
|
||||
Las compilaciones oficiales de Yandex actualmente usan GCC porque genera código de máquina de un rendimiento ligeramente mejor (con una diferencia de hasta varios por ciento según nuestros puntos de referencia). Y Clang es más conveniente para el desarrollo generalmente. Sin embargo, nuestra plataforma de integración continua (CI) ejecuta verificaciones de aproximadamente una docena de combinaciones de compilación.
|
||||
|
||||
Para instalar GCC en Ubuntu, ejecute: `sudo apt install gcc g++`
|
||||
|
||||
Compruebe la versión de gcc: `gcc --version`. Si está por debajo de 9, siga las instrucciones aquí: https://clickhouse.tech/docs/es/development/build/#install-gcc-10.
|
||||
|
||||
La compilación de Mac OS X solo es compatible con Clang. Sólo tiene que ejecutar `brew install llvm`
|
||||
|
||||
Si decide utilizar Clang, también puede instalar `libc++` y `lld` si usted sabe lo que es. Utilizar `ccache` también se recomienda.
|
||||
|
||||
# El proceso de construcción {#the-building-process}
|
||||
|
||||
Ahora que está listo para construir ClickHouse, le recomendamos que cree un directorio separado `build` dentro `ClickHouse` que contendrá todos los de la generación de artefactos:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
Puede tener varios directorios diferentes (build_release, build_debug, etc.) para diferentes tipos de construcción.
|
||||
|
||||
Mientras que dentro de la `build` directorio, configure su compilación ejecutando CMake. Antes de la primera ejecución, debe definir variables de entorno que especifiquen el compilador (compilador gcc versión 10 en este ejemplo).
|
||||
|
||||
Linux:
|
||||
|
||||
export CC=gcc-10 CXX=g++-10
|
||||
cmake ..
|
||||
|
||||
Mac OS X:
|
||||
|
||||
export CC=clang CXX=clang++
|
||||
cmake ..
|
||||
|
||||
El `CC` variable especifica el compilador para C (abreviatura de C Compiler), y `CXX` variable indica qué compilador de C ++ se usará para compilar.
|
||||
|
||||
Para una construcción más rápida, puede recurrir al `debug` tipo de compilación: una compilación sin optimizaciones. Para ese suministro el siguiente parámetro `-D CMAKE_BUILD_TYPE=Debug`:
|
||||
|
||||
cmake -D CMAKE_BUILD_TYPE=Debug ..
|
||||
|
||||
Puede cambiar el tipo de compilación ejecutando este comando en el `build` directorio.
|
||||
|
||||
Ejecutar ninja para construir:
|
||||
|
||||
ninja clickhouse-server clickhouse-client
|
||||
|
||||
Solo los binarios requeridos se van a construir en este ejemplo.
|
||||
|
||||
Si necesita construir todos los binarios (utilidades y pruebas), debe ejecutar ninja sin parámetros:
|
||||
|
||||
ninja
|
||||
|
||||
La compilación completa requiere aproximadamente 30 GB de espacio libre en disco o 15 GB para construir los binarios principales.
|
||||
|
||||
Cuando hay una gran cantidad de RAM disponible en la máquina de compilación, debe limitar el número de tareas de compilación que se ejecutan en paralelo con `-j` parámetro:
|
||||
|
||||
ninja -j 1 clickhouse-server clickhouse-client
|
||||
|
||||
En máquinas con 4GB de RAM, se recomienda especificar 1, para 8GB de RAM `-j 2` se recomienda.
|
||||
|
||||
Si recibe el mensaje: `ninja: error: loading 'build.ninja': No such file or directory`, significa que la generación de una configuración de compilación ha fallado y necesita inspeccionar el mensaje anterior.
|
||||
|
||||
Cuando se inicie correctamente el proceso de construcción, verá el progreso de la compilación: el número de tareas procesadas y el número total de tareas.
|
||||
|
||||
Al crear mensajes sobre archivos protobuf en la biblioteca libhdfs2, como `libprotobuf WARNING` puede aparecer. Afectan a nada y son seguros para ser ignorado.
|
||||
|
||||
Tras la compilación exitosa, obtienes un archivo ejecutable `ClickHouse/<build_dir>/programs/clickhouse`:
|
||||
|
||||
ls -l programs/clickhouse
|
||||
|
||||
# Ejecución del ejecutable construido de ClickHouse {#running-the-built-executable-of-clickhouse}
|
||||
|
||||
Para ejecutar el servidor bajo el usuario actual, debe navegar hasta `ClickHouse/programs/server/` (situado fuera de `build`) y ejecutar:
|
||||
|
||||
../../build/programs/clickhouse server
|
||||
|
||||
En este caso, ClickHouse usará archivos de configuración ubicados en el directorio actual. Puede ejecutar `clickhouse server` desde cualquier directorio que especifique la ruta a un archivo de configuración como un parámetro de línea de comandos `--config-file`.
|
||||
|
||||
Para conectarse a ClickHouse con clickhouse-client en otro terminal, vaya a `ClickHouse/build/programs/` y ejecutar `./clickhouse client`.
|
||||
|
||||
Si usted consigue `Connection refused` mensaje en Mac OS X o FreeBSD, intente especificar la dirección de host 127.0.0.1:
|
||||
|
||||
clickhouse client --host 127.0.0.1
|
||||
|
||||
Puede reemplazar la versión de producción del binario ClickHouse instalado en su sistema con su binario ClickHouse personalizado. Para ello, instale ClickHouse en su máquina siguiendo las instrucciones del sitio web oficial. A continuación, ejecute lo siguiente:
|
||||
|
||||
sudo service clickhouse-server stop
|
||||
sudo cp ClickHouse/build/programs/clickhouse /usr/bin/
|
||||
sudo service clickhouse-server start
|
||||
|
||||
Tenga en cuenta que `clickhouse-client`, `clickhouse-server` y otros son enlaces simbólicos a los comúnmente compartidos `clickhouse` binario.
|
||||
|
||||
También puede ejecutar su binario ClickHouse personalizado con el archivo de configuración del paquete ClickHouse instalado en su sistema:
|
||||
|
||||
sudo service clickhouse-server stop
|
||||
sudo -u clickhouse ClickHouse/build/programs/clickhouse server --config-file /etc/clickhouse-server/config.xml
|
||||
|
||||
# IDE (entorno de desarrollo integrado) {#ide-integrated-development-environment}
|
||||
|
||||
Si no sabe qué IDE usar, le recomendamos que use CLion. CLion es un software comercial, pero ofrece un período de prueba gratuito de 30 días. También es gratuito para los estudiantes. CLion se puede usar tanto en Linux como en Mac OS X.
|
||||
|
||||
KDevelop y QTCreator son otras excelentes alternativas de un IDE para desarrollar ClickHouse. KDevelop viene como un IDE muy útil aunque inestable. Si KDevelop se bloquea después de un tiempo al abrir el proyecto, debe hacer clic “Stop All” botón tan pronto como se ha abierto la lista de archivos del proyecto. Después de hacerlo, KDevelop debería estar bien para trabajar.
|
||||
|
||||
Como editores de código simples, puede usar Sublime Text o Visual Studio Code, o Kate (todos los cuales están disponibles en Linux).
|
||||
|
||||
Por si acaso, vale la pena mencionar que CLion crea `build` por sí mismo, también por sí mismo selecciona `debug` para el tipo de compilación, para la configuración usa una versión de CMake que está definida en CLion y no la instalada por usted, y finalmente, CLion usará `make` para ejecutar tareas de compilación en lugar de `ninja`. Este es un comportamiento normal, solo tenlo en cuenta para evitar confusiones.
|
||||
|
||||
# Código de escritura {#writing-code}
|
||||
|
||||
La descripción de la arquitectura ClickHouse se puede encontrar aquí: https://clickhouse.tech/docs/es/desarrollo/arquitectura/
|
||||
|
||||
La Guía de estilo de código: https://clickhouse.tech/docs/en/development/style/
|
||||
|
||||
Pruebas de escritura: https://clickhouse.tech/docs/en/development/tests/
|
||||
|
||||
Lista de tareas: https://github.com/ClickHouse/ClickHouse/issues?q=is%3Aopen+is%3Aissue+label%3A%22easy+task%22
|
||||
|
||||
# Datos de prueba {#test-data}
|
||||
|
||||
El desarrollo de ClickHouse a menudo requiere cargar conjuntos de datos realistas. Es particularmente importante para las pruebas de rendimiento. Tenemos un conjunto especialmente preparado de datos anónimos de Yandex.Métrica. Se requiere, además, unos 3 GB de espacio libre en disco. Tenga en cuenta que estos datos no son necesarios para realizar la mayoría de las tareas de desarrollo.
|
||||
|
||||
sudo apt install wget xz-utils
|
||||
|
||||
wget https://datasets.clickhouse.tech/hits/tsv/hits_v1.tsv.xz
|
||||
wget https://datasets.clickhouse.tech/visits/tsv/visits_v1.tsv.xz
|
||||
|
||||
xz -v -d hits_v1.tsv.xz
|
||||
xz -v -d visits_v1.tsv.xz
|
||||
|
||||
clickhouse-client
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS test
|
||||
|
||||
CREATE TABLE test.hits ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, `ParsedParams.Key1` Array(String), `ParsedParams.Key2` Array(String), `ParsedParams.Key3` Array(String), `ParsedParams.Key4` Array(String), `ParsedParams.Key5` Array(String), `ParsedParams.ValueDouble` Array(Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree PARTITION BY toYYYYMM(EventDate) SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID), EventTime);
|
||||
|
||||
CREATE TABLE test.visits ( CounterID UInt32, StartDate Date, Sign Int8, IsNew UInt8, VisitID UInt64, UserID UInt64, StartTime DateTime, Duration UInt32, UTCStartTime DateTime, PageViews Int32, Hits Int32, IsBounce UInt8, Referer String, StartURL String, RefererDomain String, StartURLDomain String, EndURL String, LinkURL String, IsDownload UInt8, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, PlaceID Int32, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), IsYandex UInt8, GoalReachesDepth Int32, GoalReachesURL Int32, GoalReachesAny Int32, SocialSourceNetworkID UInt8, SocialSourcePage String, MobilePhoneModel String, ClientEventTime DateTime, RegionID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RemoteIP UInt32, RemoteIP6 FixedString(16), IPNetworkID UInt32, SilverlightVersion3 UInt32, CodeVersion UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, UserAgentMajor UInt16, UserAgentMinor UInt16, WindowClientWidth UInt16, WindowClientHeight UInt16, SilverlightVersion2 UInt8, SilverlightVersion4 UInt16, FlashVersion3 UInt16, FlashVersion4 UInt16, ClientTimeZone Int16, OS UInt8, UserAgent UInt8, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, NetMajor UInt8, NetMinor UInt8, MobilePhone UInt8, SilverlightVersion1 UInt8, Age UInt8, Sex UInt8, Income UInt8, JavaEnable UInt8, CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, BrowserLanguage UInt16, BrowserCountry UInt16, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), Params Array(String), `Goals.ID` Array(UInt32), `Goals.Serial` Array(UInt32), `Goals.EventTime` Array(DateTime), `Goals.Price` Array(Int64), `Goals.OrderID` Array(String), `Goals.CurrencyID` Array(UInt32), WatchIDs Array(UInt64), ParamSumPrice Int64, ParamCurrency FixedString(3), ParamCurrencyID UInt16, ClickLogID UInt64, ClickEventID Int32, ClickGoodEvent Int32, ClickEventTime DateTime, ClickPriorityID Int32, ClickPhraseID Int32, ClickPageID Int32, ClickPlaceID Int32, ClickTypeID Int32, ClickResourceID Int32, ClickCost UInt32, ClickClientIP UInt32, ClickDomainID UInt32, ClickURL String, ClickAttempt UInt8, ClickOrderID UInt32, ClickBannerID UInt32, ClickMarketCategoryID UInt32, ClickMarketPP UInt32, ClickMarketCategoryName String, ClickMarketPPName String, ClickAWAPSCampaignName String, ClickPageName String, ClickTargetType UInt16, ClickTargetPhraseID UInt64, ClickContextType UInt8, ClickSelectType Int8, ClickOptions String, ClickGroupBannerID Int32, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, FirstVisit DateTime, PredLastVisit Date, LastVisit Date, TotalVisits UInt32, `TraficSource.ID` Array(Int8), `TraficSource.SearchEngineID` Array(UInt16), `TraficSource.AdvEngineID` Array(UInt8), `TraficSource.PlaceID` Array(UInt16), `TraficSource.SocialSourceNetworkID` Array(UInt8), `TraficSource.Domain` Array(String), `TraficSource.SearchPhrase` Array(String), `TraficSource.SocialSourcePage` Array(String), Attendance FixedString(16), CLID UInt32, YCLID UInt64, NormalizedRefererHash UInt64, SearchPhraseHash UInt64, RefererDomainHash UInt64, NormalizedStartURLHash UInt64, StartURLDomainHash UInt64, NormalizedEndURLHash UInt64, TopLevelDomain UInt64, URLScheme UInt64, OpenstatServiceNameHash UInt64, OpenstatCampaignIDHash UInt64, OpenstatAdIDHash UInt64, OpenstatSourceIDHash UInt64, UTMSourceHash UInt64, UTMMediumHash UInt64, UTMCampaignHash UInt64, UTMContentHash UInt64, UTMTermHash UInt64, FromHash UInt64, WebVisorEnabled UInt8, WebVisorActivity UInt32, `ParsedParams.Key1` Array(String), `ParsedParams.Key2` Array(String), `ParsedParams.Key3` Array(String), `ParsedParams.Key4` Array(String), `ParsedParams.Key5` Array(String), `ParsedParams.ValueDouble` Array(Float64), `Market.Type` Array(UInt8), `Market.GoalID` Array(UInt32), `Market.OrderID` Array(String), `Market.OrderPrice` Array(Int64), `Market.PP` Array(UInt32), `Market.DirectPlaceID` Array(UInt32), `Market.DirectOrderID` Array(UInt32), `Market.DirectBannerID` Array(UInt32), `Market.GoodID` Array(String), `Market.GoodName` Array(String), `Market.GoodQuantity` Array(Int32), `Market.GoodPrice` Array(Int64), IslandID FixedString(16)) ENGINE = CollapsingMergeTree(Sign) PARTITION BY toYYYYMM(StartDate) SAMPLE BY intHash32(UserID) ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID);
|
||||
|
||||
clickhouse-client --max_insert_block_size 100000 --query "INSERT INTO test.hits FORMAT TSV" < hits_v1.tsv
|
||||
clickhouse-client --max_insert_block_size 100000 --query "INSERT INTO test.visits FORMAT TSV" < visits_v1.tsv
|
||||
|
||||
# Creación de solicitud de extracción {#creating-pull-request}
|
||||
|
||||
Navega a tu repositorio de fork en la interfaz de usuario de GitHub. Si ha estado desarrollando en una sucursal, debe seleccionar esa sucursal. Habrá un “Pull request” botón situado en la pantalla. En esencia, esto significa “create a request for accepting my changes into the main repository”.
|
||||
|
||||
Se puede crear una solicitud de extracción incluso si el trabajo aún no se ha completado. En este caso, por favor ponga la palabra “WIP” (trabajo en curso) al comienzo del título, se puede cambiar más tarde. Esto es útil para la revisión cooperativa y la discusión de los cambios, así como para ejecutar todas las pruebas disponibles. Es importante que proporcione una breve descripción de sus cambios, que más tarde se utilizará para generar registros de cambios de lanzamiento.
|
||||
|
||||
Las pruebas comenzarán tan pronto como los empleados de Yandex etiqueten su PR con una etiqueta “can be tested”. The results of some first checks (e.g. code style) will come in within several minutes. Build check results will arrive within half an hour. And the main set of tests will report itself within an hour.
|
||||
|
||||
El sistema preparará compilaciones binarias ClickHouse para su solicitud de extracción individualmente. Para recuperar estas compilaciones, haga clic en “Details” junto al link “ClickHouse build check” en la lista de cheques. Allí encontrará enlaces directos a la construcción.deb paquetes de ClickHouse que puede implementar incluso en sus servidores de producción (si no tiene miedo).
|
||||
|
||||
Lo más probable es que algunas de las compilaciones fallen las primeras veces. Esto se debe al hecho de que verificamos las compilaciones tanto con gcc como con clang, con casi todas las advertencias existentes (siempre con el `-Werror` bandera) habilitado para sonido. En esa misma página, puede encontrar todos los registros de compilación para que no tenga que compilar ClickHouse de todas las formas posibles.
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Desarrollo
|
||||
toc_hidden: true
|
||||
toc_priority: 58
|
||||
toc_title: oculto
|
||||
---
|
||||
|
||||
# Desarrollo de ClickHouse {#clickhouse-development}
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/development/) <!--hide-->
|
@ -1,841 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 68
|
||||
toc_title: "C\xF3mo escribir c\xF3digo C ++"
|
||||
---
|
||||
|
||||
# Cómo escribir código C ++ {#how-to-write-c-code}
|
||||
|
||||
## Recomendaciones generales {#general-recommendations}
|
||||
|
||||
**1.** Las siguientes son recomendaciones, no requisitos.
|
||||
|
||||
**2.** Si está editando código, tiene sentido seguir el formato del código existente.
|
||||
|
||||
**3.** El estilo de código es necesario para la coherencia. La consistencia facilita la lectura del código y también facilita la búsqueda del código.
|
||||
|
||||
**4.** Muchas de las reglas no tienen razones lógicas; están dictadas por prácticas establecidas.
|
||||
|
||||
## Formatear {#formatting}
|
||||
|
||||
**1.** La mayor parte del formato se realizará automáticamente por `clang-format`.
|
||||
|
||||
**2.** Las sangrías son 4 espacios. Configure el entorno de desarrollo para que una pestaña agregue cuatro espacios.
|
||||
|
||||
**3.** Abrir y cerrar llaves deben estar en una línea separada.
|
||||
|
||||
``` cpp
|
||||
inline void readBoolText(bool & x, ReadBuffer & buf)
|
||||
{
|
||||
char tmp = '0';
|
||||
readChar(tmp, buf);
|
||||
x = tmp != '0';
|
||||
}
|
||||
```
|
||||
|
||||
**4.** Si todo el cuerpo de la función es `statement`, se puede colocar en una sola línea. Coloque espacios alrededor de llaves (además del espacio al final de la línea).
|
||||
|
||||
``` cpp
|
||||
inline size_t mask() const { return buf_size() - 1; }
|
||||
inline size_t place(HashValue x) const { return x & mask(); }
|
||||
```
|
||||
|
||||
**5.** Para funciones. No coloque espacios alrededor de los corchetes.
|
||||
|
||||
``` cpp
|
||||
void reinsert(const Value & x)
|
||||
```
|
||||
|
||||
``` cpp
|
||||
memcpy(&buf[place_value], &x, sizeof(x));
|
||||
```
|
||||
|
||||
**6.** En `if`, `for`, `while` y otras expresiones, se inserta un espacio delante del corchete de apertura (a diferencia de las llamadas a funciones).
|
||||
|
||||
``` cpp
|
||||
for (size_t i = 0; i < rows; i += storage.index_granularity)
|
||||
```
|
||||
|
||||
**7.** Agregar espacios alrededor de los operadores binarios (`+`, `-`, `*`, `/`, `%`, …) and the ternary operator `?:`.
|
||||
|
||||
``` cpp
|
||||
UInt16 year = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0');
|
||||
UInt8 month = (s[5] - '0') * 10 + (s[6] - '0');
|
||||
UInt8 day = (s[8] - '0') * 10 + (s[9] - '0');
|
||||
```
|
||||
|
||||
**8.** Si se introduce un avance de línea, coloque al operador en una nueva línea y aumente la sangría antes de ella.
|
||||
|
||||
``` cpp
|
||||
if (elapsed_ns)
|
||||
message << " ("
|
||||
<< rows_read_on_server * 1000000000 / elapsed_ns << " rows/s., "
|
||||
<< bytes_read_on_server * 1000.0 / elapsed_ns << " MB/s.) ";
|
||||
```
|
||||
|
||||
**9.** Puede utilizar espacios para la alineación dentro de una línea, si lo desea.
|
||||
|
||||
``` cpp
|
||||
dst.ClickLogID = click.LogID;
|
||||
dst.ClickEventID = click.EventID;
|
||||
dst.ClickGoodEvent = click.GoodEvent;
|
||||
```
|
||||
|
||||
**10.** No use espacios alrededor de los operadores `.`, `->`.
|
||||
|
||||
Si es necesario, el operador se puede envolver a la siguiente línea. En este caso, el desplazamiento frente a él aumenta.
|
||||
|
||||
**11.** No utilice un espacio para separar los operadores unarios (`--`, `++`, `*`, `&`, …) from the argument.
|
||||
|
||||
**12.** Pon un espacio después de una coma, pero no antes. La misma regla se aplica a un punto y coma dentro de un `for` expresion.
|
||||
|
||||
**13.** No utilice espacios para separar el `[]` operador.
|
||||
|
||||
**14.** En un `template <...>` expresión, use un espacio entre `template` y `<`; sin espacios después de `<` o antes `>`.
|
||||
|
||||
``` cpp
|
||||
template <typename TKey, typename TValue>
|
||||
struct AggregatedStatElement
|
||||
{}
|
||||
```
|
||||
|
||||
**15.** En clases y estructuras, escribe `public`, `private`, y `protected` en el mismo nivel que `class/struct`, y sangrar el resto del código.
|
||||
|
||||
``` cpp
|
||||
template <typename T>
|
||||
class MultiVersion
|
||||
{
|
||||
public:
|
||||
/// Version of object for usage. shared_ptr manage lifetime of version.
|
||||
using Version = std::shared_ptr<const T>;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
**16.** Si el mismo `namespace` se usa para todo el archivo, y no hay nada más significativo, no es necesario un desplazamiento dentro `namespace`.
|
||||
|
||||
**17.** Si el bloque para un `if`, `for`, `while`, u otra expresión consiste en una sola `statement`, las llaves son opcionales. Coloque el `statement` en una línea separada, en su lugar. Esta regla también es válida para `if`, `for`, `while`, …
|
||||
|
||||
Pero si el interior `statement` contiene llaves o `else`, el bloque externo debe escribirse entre llaves.
|
||||
|
||||
``` cpp
|
||||
/// Finish write.
|
||||
for (auto & stream : streams)
|
||||
stream.second->finalize();
|
||||
```
|
||||
|
||||
**18.** No debería haber espacios al final de las líneas.
|
||||
|
||||
**19.** Los archivos de origen están codificados en UTF-8.
|
||||
|
||||
**20.** Los caracteres no ASCII se pueden usar en literales de cadena.
|
||||
|
||||
``` cpp
|
||||
<< ", " << (timer.elapsed() / chunks_stats.hits) << " μsec/hit.";
|
||||
```
|
||||
|
||||
**21.** No escriba varias expresiones en una sola línea.
|
||||
|
||||
**22.** Agrupe secciones de código dentro de las funciones y sepárelas con no más de una línea vacía.
|
||||
|
||||
**23.** Separe funciones, clases, etc. con una o dos líneas vacías.
|
||||
|
||||
**24.** `A const` (relacionado con un valor) debe escribirse antes del nombre del tipo.
|
||||
|
||||
``` cpp
|
||||
//correct
|
||||
const char * pos
|
||||
const std::string & s
|
||||
//incorrect
|
||||
char const * pos
|
||||
```
|
||||
|
||||
**25.** Al declarar un puntero o referencia, el `*` y `&` Los símbolos deben estar separados por espacios en ambos lados.
|
||||
|
||||
``` cpp
|
||||
//correct
|
||||
const char * pos
|
||||
//incorrect
|
||||
const char* pos
|
||||
const char *pos
|
||||
```
|
||||
|
||||
**26.** Cuando utilice tipos de plantilla, alias con el `using` palabra clave (excepto en los casos más simples).
|
||||
|
||||
En otras palabras, los parámetros de la plantilla se especifican solo en `using` y no se repiten en el código.
|
||||
|
||||
`using` se puede declarar localmente, como dentro de una función.
|
||||
|
||||
``` cpp
|
||||
//correct
|
||||
using FileStreams = std::map<std::string, std::shared_ptr<Stream>>;
|
||||
FileStreams streams;
|
||||
//incorrect
|
||||
std::map<std::string, std::shared_ptr<Stream>> streams;
|
||||
```
|
||||
|
||||
**27.** No declare varias variables de diferentes tipos en una instrucción.
|
||||
|
||||
``` cpp
|
||||
//incorrect
|
||||
int x, *y;
|
||||
```
|
||||
|
||||
**28.** No utilice moldes de estilo C.
|
||||
|
||||
``` cpp
|
||||
//incorrect
|
||||
std::cerr << (int)c <<; std::endl;
|
||||
//correct
|
||||
std::cerr << static_cast<int>(c) << std::endl;
|
||||
```
|
||||
|
||||
**29.** En clases y estructuras, los miembros del grupo y las funciones por separado dentro de cada ámbito de visibilidad.
|
||||
|
||||
**30.** Para clases y estructuras pequeñas, no es necesario separar la declaración del método de la implementación.
|
||||
|
||||
Lo mismo es cierto para los métodos pequeños en cualquier clase o estructura.
|
||||
|
||||
Para clases y estructuras con plantillas, no separe las declaraciones de métodos de la implementación (porque de lo contrario deben definirse en la misma unidad de traducción).
|
||||
|
||||
**31.** Puede ajustar líneas en 140 caracteres, en lugar de 80.
|
||||
|
||||
**32.** Utilice siempre los operadores de incremento / decremento de prefijo si no se requiere postfix.
|
||||
|
||||
``` cpp
|
||||
for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it)
|
||||
```
|
||||
|
||||
## Comentario {#comments}
|
||||
|
||||
**1.** Asegúrese de agregar comentarios para todas las partes no triviales del código.
|
||||
|
||||
Esto es muy importante. Escribir el comentario puede ayudarte a darte cuenta de que el código no es necesario o que está diseñado incorrectamente.
|
||||
|
||||
``` cpp
|
||||
/** Part of piece of memory, that can be used.
|
||||
* For example, if internal_buffer is 1MB, and there was only 10 bytes loaded to buffer from file for reading,
|
||||
* then working_buffer will have size of only 10 bytes
|
||||
* (working_buffer.end() will point to position right after those 10 bytes available for read).
|
||||
*/
|
||||
```
|
||||
|
||||
**2.** Los comentarios pueden ser tan detallados como sea necesario.
|
||||
|
||||
**3.** Coloque comentarios antes del código que describen. En casos raros, los comentarios pueden aparecer después del código, en la misma línea.
|
||||
|
||||
``` cpp
|
||||
/** Parses and executes the query.
|
||||
*/
|
||||
void executeQuery(
|
||||
ReadBuffer & istr, /// Where to read the query from (and data for INSERT, if applicable)
|
||||
WriteBuffer & ostr, /// Where to write the result
|
||||
Context & context, /// DB, tables, data types, engines, functions, aggregate functions...
|
||||
BlockInputStreamPtr & query_plan, /// Here could be written the description on how query was executed
|
||||
QueryProcessingStage::Enum stage = QueryProcessingStage::Complete /// Up to which stage process the SELECT query
|
||||
)
|
||||
```
|
||||
|
||||
**4.** Los comentarios deben escribirse en inglés solamente.
|
||||
|
||||
**5.** Si está escribiendo una biblioteca, incluya comentarios detallados que la expliquen en el archivo de encabezado principal.
|
||||
|
||||
**6.** No agregue comentarios que no proporcionen información adicional. En particular, no deje comentarios vacíos como este:
|
||||
|
||||
``` cpp
|
||||
/*
|
||||
* Procedure Name:
|
||||
* Original procedure name:
|
||||
* Author:
|
||||
* Date of creation:
|
||||
* Dates of modification:
|
||||
* Modification authors:
|
||||
* Original file name:
|
||||
* Purpose:
|
||||
* Intent:
|
||||
* Designation:
|
||||
* Classes used:
|
||||
* Constants:
|
||||
* Local variables:
|
||||
* Parameters:
|
||||
* Date of creation:
|
||||
* Purpose:
|
||||
*/
|
||||
```
|
||||
|
||||
El ejemplo se toma prestado del recurso http://home.tamk.fi/~jaalto/course/coding-style/doc/unmaintainable-code/.
|
||||
|
||||
**7.** No escriba comentarios de basura (autor, fecha de creación ..) al principio de cada archivo.
|
||||
|
||||
**8.** Los comentarios de una sola línea comienzan con tres barras: `///` y los comentarios de varias líneas comienzan con `/**`. Estos comentarios son considerados “documentation”.
|
||||
|
||||
Nota: Puede usar Doxygen para generar documentación a partir de estos comentarios. Pero Doxygen no se usa generalmente porque es más conveniente navegar por el código en el IDE.
|
||||
|
||||
**9.** Los comentarios de varias líneas no deben tener líneas vacías al principio y al final (excepto la línea que cierra un comentario de varias líneas).
|
||||
|
||||
**10.** Para comentar el código, use comentarios básicos, no “documenting” comentario.
|
||||
|
||||
**11.** Elimine las partes comentadas del código antes de confirmar.
|
||||
|
||||
**12.** No use blasfemias en comentarios o código.
|
||||
|
||||
**13.** No use letras mayúsculas. No use puntuación excesiva.
|
||||
|
||||
``` cpp
|
||||
/// WHAT THE FAIL???
|
||||
```
|
||||
|
||||
**14.** No use comentarios para hacer delímetros.
|
||||
|
||||
``` cpp
|
||||
///******************************************************
|
||||
```
|
||||
|
||||
**15.** No comiencen las discusiones en los comentarios.
|
||||
|
||||
``` cpp
|
||||
/// Why did you do this stuff?
|
||||
```
|
||||
|
||||
**16.** No es necesario escribir un comentario al final de un bloque que describa de qué se trataba.
|
||||
|
||||
``` cpp
|
||||
/// for
|
||||
```
|
||||
|
||||
## Nombre {#names}
|
||||
|
||||
**1.** Use letras minúsculas con guiones bajos en los nombres de variables y miembros de clase.
|
||||
|
||||
``` cpp
|
||||
size_t max_block_size;
|
||||
```
|
||||
|
||||
**2.** Para los nombres de las funciones (métodos), use camelCase comenzando con una letra minúscula.
|
||||
|
||||
``` cpp
|
||||
std::string getName() const override { return "Memory"; }
|
||||
```
|
||||
|
||||
**3.** Para los nombres de las clases (estructuras), use CamelCase comenzando con una letra mayúscula. Los prefijos distintos de I no se usan para interfaces.
|
||||
|
||||
``` cpp
|
||||
class StorageMemory : public IStorage
|
||||
```
|
||||
|
||||
**4.** `using` se nombran de la misma manera que las clases, o con `_t` al final.
|
||||
|
||||
**5.** Nombres de argumentos de tipo de plantilla: en casos simples, use `T`; `T`, `U`; `T1`, `T2`.
|
||||
|
||||
Para casos más complejos, siga las reglas para los nombres de clase o agregue el prefijo `T`.
|
||||
|
||||
``` cpp
|
||||
template <typename TKey, typename TValue>
|
||||
struct AggregatedStatElement
|
||||
```
|
||||
|
||||
**6.** Nombres de argumentos constantes de plantilla: siga las reglas para los nombres de variables o use `N` en casos simples.
|
||||
|
||||
``` cpp
|
||||
template <bool without_www>
|
||||
struct ExtractDomain
|
||||
```
|
||||
|
||||
**7.** Para clases abstractas (interfaces) puede agregar el `I` prefijo.
|
||||
|
||||
``` cpp
|
||||
class IBlockInputStream
|
||||
```
|
||||
|
||||
**8.** Si usa una variable localmente, puede usar el nombre corto.
|
||||
|
||||
En todos los demás casos, use un nombre que describa el significado.
|
||||
|
||||
``` cpp
|
||||
bool info_successfully_loaded = false;
|
||||
```
|
||||
|
||||
**9.** Nombres de `define`s y las constantes globales usan ALL_CAPS con guiones bajos.
|
||||
|
||||
``` cpp
|
||||
#define MAX_SRC_TABLE_NAMES_TO_STORE 1000
|
||||
```
|
||||
|
||||
**10.** Los nombres de archivo deben usar el mismo estilo que su contenido.
|
||||
|
||||
Si un archivo contiene una sola clase, nombre el archivo de la misma manera que la clase (CamelCase).
|
||||
|
||||
Si el archivo contiene una sola función, nombre el archivo de la misma manera que la función (camelCase).
|
||||
|
||||
**11.** Si el nombre contiene una abreviatura, :
|
||||
|
||||
- Para los nombres de variables, la abreviatura debe usar letras minúsculas `mysql_connection` (ni `mySQL_connection`).
|
||||
- Para los nombres de clases y funciones, mantenga las letras mayúsculas en la abreviatura`MySQLConnection` (ni `MySqlConnection`).
|
||||
|
||||
**12.** Los argumentos del constructor que se usan solo para inicializar los miembros de la clase deben nombrarse de la misma manera que los miembros de la clase, pero con un guión bajo al final.
|
||||
|
||||
``` cpp
|
||||
FileQueueProcessor(
|
||||
const std::string & path_,
|
||||
const std::string & prefix_,
|
||||
std::shared_ptr<FileHandler> handler_)
|
||||
: path(path_),
|
||||
prefix(prefix_),
|
||||
handler(handler_),
|
||||
log(&Logger::get("FileQueueProcessor"))
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
El sufijo de subrayado se puede omitir si el argumento no se usa en el cuerpo del constructor.
|
||||
|
||||
**13.** No hay diferencia en los nombres de las variables locales y los miembros de la clase (no se requieren prefijos).
|
||||
|
||||
``` cpp
|
||||
timer (not m_timer)
|
||||
```
|
||||
|
||||
**14.** Para las constantes en un `enum`, usar CamelCase con una letra mayúscula. ALL_CAPS también es aceptable. Si el `enum` no es local, utilice un `enum class`.
|
||||
|
||||
``` cpp
|
||||
enum class CompressionMethod
|
||||
{
|
||||
QuickLZ = 0,
|
||||
LZ4 = 1,
|
||||
};
|
||||
```
|
||||
|
||||
**15.** Todos los nombres deben estar en inglés. La transliteración de palabras rusas no está permitida.
|
||||
|
||||
not Stroka
|
||||
|
||||
**16.** Las abreviaturas son aceptables si son bien conocidas (cuando puede encontrar fácilmente el significado de la abreviatura en Wikipedia o en un motor de búsqueda).
|
||||
|
||||
`AST`, `SQL`.
|
||||
|
||||
Not `NVDH` (some random letters)
|
||||
|
||||
Las palabras incompletas son aceptables si la versión abreviada es de uso común.
|
||||
|
||||
También puede usar una abreviatura si el nombre completo se incluye junto a él en los comentarios.
|
||||
|
||||
**17.** Los nombres de archivo con código fuente de C++ deben tener `.cpp` ampliación. Los archivos de encabezado deben tener `.h` ampliación.
|
||||
|
||||
## Cómo escribir código {#how-to-write-code}
|
||||
|
||||
**1.** Gestión de la memoria.
|
||||
|
||||
Desasignación de memoria manual (`delete`) solo se puede usar en el código de la biblioteca.
|
||||
|
||||
En el código de la biblioteca, el `delete` operador sólo se puede utilizar en destructores.
|
||||
|
||||
En el código de la aplicación, la memoria debe ser liberada por el objeto que la posee.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
- La forma más fácil es colocar un objeto en la pila o convertirlo en miembro de otra clase.
|
||||
- Para una gran cantidad de objetos pequeños, use contenedores.
|
||||
- Para la desasignación automática de un pequeño número de objetos que residen en el montón, use `shared_ptr/unique_ptr`.
|
||||
|
||||
**2.** Gestión de recursos.
|
||||
|
||||
Utilizar `RAII` y ver arriba.
|
||||
|
||||
**3.** Manejo de errores.
|
||||
|
||||
Utilice excepciones. En la mayoría de los casos, solo necesita lanzar una excepción y no necesita atraparla (debido a `RAII`).
|
||||
|
||||
En las aplicaciones de procesamiento de datos fuera de línea, a menudo es aceptable no detectar excepciones.
|
||||
|
||||
En los servidores que manejan las solicitudes de los usuarios, generalmente es suficiente detectar excepciones en el nivel superior del controlador de conexión.
|
||||
|
||||
En las funciones de subproceso, debe capturar y mantener todas las excepciones para volver a lanzarlas en el subproceso principal después `join`.
|
||||
|
||||
``` cpp
|
||||
/// If there weren't any calculations yet, calculate the first block synchronously
|
||||
if (!started)
|
||||
{
|
||||
calculate();
|
||||
started = true;
|
||||
}
|
||||
else /// If calculations are already in progress, wait for the result
|
||||
pool.wait();
|
||||
|
||||
if (exception)
|
||||
exception->rethrow();
|
||||
```
|
||||
|
||||
Nunca oculte excepciones sin manejo. Nunca simplemente ponga ciegamente todas las excepciones para iniciar sesión.
|
||||
|
||||
``` cpp
|
||||
//Not correct
|
||||
catch (...) {}
|
||||
```
|
||||
|
||||
Si necesita ignorar algunas excepciones, hágalo solo para las específicas y vuelva a lanzar el resto.
|
||||
|
||||
``` cpp
|
||||
catch (const DB::Exception & e)
|
||||
{
|
||||
if (e.code() == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION)
|
||||
return nullptr;
|
||||
else
|
||||
throw;
|
||||
}
|
||||
```
|
||||
|
||||
Al usar funciones con códigos de respuesta o `errno`, siempre verifique el resultado y arroje una excepción en caso de error.
|
||||
|
||||
``` cpp
|
||||
if (0 != close(fd))
|
||||
throwFromErrno("Cannot close file " + file_name, ErrorCodes::CANNOT_CLOSE_FILE);
|
||||
```
|
||||
|
||||
`Do not use assert`.
|
||||
|
||||
**4.** Tipos de excepción.
|
||||
|
||||
No es necesario utilizar una jerarquía de excepciones compleja en el código de la aplicación. El texto de excepción debe ser comprensible para un administrador del sistema.
|
||||
|
||||
**5.** Lanzar excepciones de destructores.
|
||||
|
||||
Esto no es recomendable, pero está permitido.
|
||||
|
||||
Utilice las siguientes opciones:
|
||||
|
||||
- Crear una función (`done()` o `finalize()`) que hará todo el trabajo de antemano que podría conducir a una excepción. Si se llamó a esa función, no debería haber excepciones en el destructor más adelante.
|
||||
- Las tareas que son demasiado complejas (como enviar mensajes a través de la red) se pueden poner en un método separado al que el usuario de la clase tendrá que llamar antes de la destrucción.
|
||||
- Si hay una excepción en el destructor, es mejor registrarla que ocultarla (si el registrador está disponible).
|
||||
- En aplicaciones simples, es aceptable confiar en `std::terminate` (para los casos de `noexcept` de forma predeterminada en C ++ 11) para manejar excepciones.
|
||||
|
||||
**6.** Bloques de código anónimos.
|
||||
|
||||
Puede crear un bloque de código separado dentro de una sola función para hacer que ciertas variables sean locales, de modo que se llame a los destructores al salir del bloque.
|
||||
|
||||
``` cpp
|
||||
Block block = data.in->read();
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
data.ready = true;
|
||||
data.block = block;
|
||||
}
|
||||
|
||||
ready_any.set();
|
||||
```
|
||||
|
||||
**7.** Multithreading.
|
||||
|
||||
En programas de procesamiento de datos fuera de línea:
|
||||
|
||||
- Trate de obtener el mejor rendimiento posible en un solo núcleo de CPU. A continuación, puede paralelizar su código si es necesario.
|
||||
|
||||
En aplicaciones de servidor:
|
||||
|
||||
- Utilice el grupo de subprocesos para procesar solicitudes. En este punto, no hemos tenido ninguna tarea que requiera el cambio de contexto de espacio de usuario.
|
||||
|
||||
La horquilla no se usa para la paralelización.
|
||||
|
||||
**8.** Sincronización de hilos.
|
||||
|
||||
A menudo es posible hacer que diferentes hilos usen diferentes celdas de memoria (incluso mejor: diferentes líneas de caché) y no usar ninguna sincronización de hilos (excepto `joinAll`).
|
||||
|
||||
Si se requiere sincronización, en la mayoría de los casos, es suficiente usar mutex bajo `lock_guard`.
|
||||
|
||||
En otros casos, use primitivas de sincronización del sistema. No utilice la espera ocupada.
|
||||
|
||||
Las operaciones atómicas deben usarse solo en los casos más simples.
|
||||
|
||||
No intente implementar estructuras de datos sin bloqueo a menos que sea su principal área de especialización.
|
||||
|
||||
**9.** Punteros vs referencias.
|
||||
|
||||
En la mayoría de los casos, prefiera referencias.
|
||||
|
||||
**10.** Construir.
|
||||
|
||||
Usar referencias constantes, punteros a constantes, `const_iterator`, y métodos const.
|
||||
|
||||
Considerar `const` para ser predeterminado y usar no-`const` sólo cuando sea necesario.
|
||||
|
||||
Al pasar variables por valor, usando `const` por lo general no tiene sentido.
|
||||
|
||||
**11.** sin firmar.
|
||||
|
||||
Utilizar `unsigned` si es necesario.
|
||||
|
||||
**12.** Tipos numéricos.
|
||||
|
||||
Utilice los tipos `UInt8`, `UInt16`, `UInt32`, `UInt64`, `Int8`, `Int16`, `Int32`, y `Int64`, así como `size_t`, `ssize_t`, y `ptrdiff_t`.
|
||||
|
||||
No use estos tipos para números: `signed/unsigned long`, `long long`, `short`, `signed/unsigned char`, `char`.
|
||||
|
||||
**13.** Pasando argumentos.
|
||||
|
||||
Pasar valores complejos por referencia (incluyendo `std::string`).
|
||||
|
||||
Si una función captura la propiedad de un objeto creado en el montón, cree el tipo de argumento `shared_ptr` o `unique_ptr`.
|
||||
|
||||
**14.** Valores devueltos.
|
||||
|
||||
En la mayoría de los casos, sólo tiene que utilizar `return`. No escribir `return std::move(res)`.
|
||||
|
||||
Si la función asigna un objeto en el montón y lo devuelve, use `shared_ptr` o `unique_ptr`.
|
||||
|
||||
En casos excepcionales, es posible que deba devolver el valor a través de un argumento. En este caso, el argumento debe ser una referencia.
|
||||
|
||||
``` cpp
|
||||
using AggregateFunctionPtr = std::shared_ptr<IAggregateFunction>;
|
||||
|
||||
/** Allows creating an aggregate function by its name.
|
||||
*/
|
||||
class AggregateFunctionFactory
|
||||
{
|
||||
public:
|
||||
AggregateFunctionFactory();
|
||||
AggregateFunctionPtr get(const String & name, const DataTypes & argument_types) const;
|
||||
```
|
||||
|
||||
**15.** espacio de nombres.
|
||||
|
||||
No hay necesidad de usar un `namespace` para el código de aplicación.
|
||||
|
||||
Las bibliotecas pequeñas tampoco necesitan esto.
|
||||
|
||||
Para bibliotecas medianas a grandes, coloque todo en un `namespace`.
|
||||
|
||||
En la biblioteca `.h` archivo, se puede utilizar `namespace detail` para ocultar los detalles de implementación no necesarios para el código de la aplicación.
|
||||
|
||||
En un `.cpp` archivo, puede usar un `static` o espacio de nombres anónimo para ocultar símbolos.
|
||||
|
||||
Además, un `namespace` puede ser utilizado para un `enum` para evitar que los nombres correspondientes caigan en un `namespace` (pero es mejor usar un `enum class`).
|
||||
|
||||
**16.** Inicialización diferida.
|
||||
|
||||
Si se requieren argumentos para la inicialización, normalmente no debe escribir un constructor predeterminado.
|
||||
|
||||
Si más adelante tendrá que retrasar la inicialización, puede agregar un constructor predeterminado que creará un objeto no válido. O, para un pequeño número de objetos, puede usar `shared_ptr/unique_ptr`.
|
||||
|
||||
``` cpp
|
||||
Loader(DB::Connection * connection_, const std::string & query, size_t max_block_size_);
|
||||
|
||||
/// For deferred initialization
|
||||
Loader() {}
|
||||
```
|
||||
|
||||
**17.** Funciones virtuales.
|
||||
|
||||
Si la clase no está destinada para uso polimórfico, no necesita hacer que las funciones sean virtuales. Esto también se aplica al destructor.
|
||||
|
||||
**18.** Codificación.
|
||||
|
||||
Usa UTF-8 en todas partes. Utilizar `std::string`y`char *`. No use `std::wstring`y`wchar_t`.
|
||||
|
||||
**19.** Tala.
|
||||
|
||||
Vea los ejemplos en todas partes del código.
|
||||
|
||||
Antes de confirmar, elimine todo el registro de depuración y sin sentido, y cualquier otro tipo de salida de depuración.
|
||||
|
||||
Se debe evitar el registro en ciclos, incluso en el nivel Trace.
|
||||
|
||||
Los registros deben ser legibles en cualquier nivel de registro.
|
||||
|
||||
El registro solo debe usarse en el código de la aplicación, en su mayor parte.
|
||||
|
||||
Los mensajes de registro deben estar escritos en inglés.
|
||||
|
||||
El registro debe ser preferiblemente comprensible para el administrador del sistema.
|
||||
|
||||
No use blasfemias en el registro.
|
||||
|
||||
Utilice la codificación UTF-8 en el registro. En casos excepcionales, puede usar caracteres que no sean ASCII en el registro.
|
||||
|
||||
**20.** Entrada-salida.
|
||||
|
||||
No utilice `iostreams` en ciclos internos que son críticos para el rendimiento de la aplicación (y nunca usan `stringstream`).
|
||||
|
||||
Utilice el `DB/IO` biblioteca en su lugar.
|
||||
|
||||
**21.** Fecha y hora.
|
||||
|
||||
Ver el `DateLUT` biblioteca.
|
||||
|
||||
**22.** incluir.
|
||||
|
||||
Utilice siempre `#pragma once` en lugar de incluir guardias.
|
||||
|
||||
**23.** utilizar.
|
||||
|
||||
`using namespace` no se utiliza. Usted puede utilizar `using` con algo específico. Pero hazlo local dentro de una clase o función.
|
||||
|
||||
**24.** No use `trailing return type` para funciones a menos que sea necesario.
|
||||
|
||||
``` cpp
|
||||
auto f() -> void
|
||||
```
|
||||
|
||||
**25.** Declaración e inicialización de variables.
|
||||
|
||||
``` cpp
|
||||
//right way
|
||||
std::string s = "Hello";
|
||||
std::string s{"Hello"};
|
||||
|
||||
//wrong way
|
||||
auto s = std::string{"Hello"};
|
||||
```
|
||||
|
||||
**26.** Para funciones virtuales, escriba `virtual` en la clase base, pero escribe `override` en lugar de `virtual` en las clases descendientes.
|
||||
|
||||
## Características no utilizadas de C ++ {#unused-features-of-c}
|
||||
|
||||
**1.** La herencia virtual no se utiliza.
|
||||
|
||||
**2.** Los especificadores de excepción de C ++ 03 no se usan.
|
||||
|
||||
## Plataforma {#platform}
|
||||
|
||||
**1.** Escribimos código para una plataforma específica.
|
||||
|
||||
Pero en igualdad de condiciones, se prefiere el código multiplataforma o portátil.
|
||||
|
||||
**2.** Idioma: C++20.
|
||||
|
||||
**3.** Compilación: `gcc`. En este momento (agosto 2020), el código se compila utilizando la versión 9.3. (También se puede compilar usando `clang 8`.)
|
||||
|
||||
Se utiliza la biblioteca estándar (`libc++`).
|
||||
|
||||
**4.**OS: Linux Ubuntu, no más viejo que Precise.
|
||||
|
||||
**5.**El código está escrito para la arquitectura de CPU x86_64.
|
||||
|
||||
El conjunto de instrucciones de CPU es el conjunto mínimo admitido entre nuestros servidores. Actualmente, es SSE 4.2.
|
||||
|
||||
**6.** Utilizar `-Wall -Wextra -Werror` flags de compilación.
|
||||
|
||||
**7.** Use enlaces estáticos con todas las bibliotecas, excepto aquellas a las que son difíciles de conectar estáticamente (consulte la salida de la `ldd` comando).
|
||||
|
||||
**8.** El código se desarrolla y se depura con la configuración de la versión.
|
||||
|
||||
## Herramienta {#tools}
|
||||
|
||||
**1.** KDevelop es un buen IDE.
|
||||
|
||||
**2.** Para la depuración, use `gdb`, `valgrind` (`memcheck`), `strace`, `-fsanitize=...`, o `tcmalloc_minimal_debug`.
|
||||
|
||||
**3.** Para crear perfiles, use `Linux Perf`, `valgrind` (`callgrind`), o `strace -cf`.
|
||||
|
||||
**4.** Las fuentes están en Git.
|
||||
|
||||
**5.** Usos de ensamblaje `CMake`.
|
||||
|
||||
**6.** Los programas se lanzan usando `deb` paquete.
|
||||
|
||||
**7.** Los compromisos a dominar no deben romper la compilación.
|
||||
|
||||
Aunque solo las revisiones seleccionadas se consideran viables.
|
||||
|
||||
**8.** Realice confirmaciones tan a menudo como sea posible, incluso si el código está parcialmente listo.
|
||||
|
||||
Use ramas para este propósito.
|
||||
|
||||
Si su código en el `master` branch todavía no se puede construir, excluirlo de la compilación antes de la `push`. Tendrá que terminarlo o eliminarlo dentro de unos días.
|
||||
|
||||
**9.** Para cambios no triviales, use ramas y publíquelas en el servidor.
|
||||
|
||||
**10.** El código no utilizado se elimina del repositorio.
|
||||
|
||||
## Biblioteca {#libraries}
|
||||
|
||||
**1.** Se utiliza la biblioteca estándar de C++20 (se permiten extensiones experimentales), así como `boost` y `Poco` marco.
|
||||
|
||||
**2.** Si es necesario, puede usar cualquier biblioteca conocida disponible en el paquete del sistema operativo.
|
||||
|
||||
Si ya hay una buena solución disponible, úsela, incluso si eso significa que debe instalar otra biblioteca.
|
||||
|
||||
(Pero prepárese para eliminar las bibliotecas incorrectas del código.)
|
||||
|
||||
**3.** Puede instalar una biblioteca que no esté en los paquetes, si los paquetes no tienen lo que necesita o tienen una versión obsoleta o el tipo de compilación incorrecto.
|
||||
|
||||
**4.** Si la biblioteca es pequeña y no tiene su propio sistema de compilación complejo, coloque los archivos `contrib` carpeta.
|
||||
|
||||
**5.** Siempre se da preferencia a las bibliotecas que ya están en uso.
|
||||
|
||||
## Recomendaciones generales {#general-recommendations-1}
|
||||
|
||||
**1.** Escribe el menor código posible.
|
||||
|
||||
**2.** Pruebe la solución más simple.
|
||||
|
||||
**3.** No escriba código hasta que sepa cómo va a funcionar y cómo funcionará el bucle interno.
|
||||
|
||||
**4.** En los casos más simples, use `using` en lugar de clases o estructuras.
|
||||
|
||||
**5.** Si es posible, no escriba constructores de copia, operadores de asignación, destructores (que no sean virtuales, si la clase contiene al menos una función virtual), mueva constructores o mueva operadores de asignación. En otras palabras, las funciones generadas por el compilador deben funcionar correctamente. Usted puede utilizar `default`.
|
||||
|
||||
**6.** Se fomenta la simplificación del código. Reduzca el tamaño de su código siempre que sea posible.
|
||||
|
||||
## Recomendaciones adicionales {#additional-recommendations}
|
||||
|
||||
**1.** Especificar explícitamente `std::` para tipos de `stddef.h`
|
||||
|
||||
no se recomienda. En otras palabras, recomendamos escribir `size_t` en su lugar `std::size_t` porque es más corto.
|
||||
|
||||
Es aceptable agregar `std::`.
|
||||
|
||||
**2.** Especificar explícitamente `std::` para funciones de la biblioteca C estándar
|
||||
|
||||
no se recomienda. En otras palabras, escribir `memcpy` en lugar de `std::memcpy`.
|
||||
|
||||
La razón es que hay funciones no estándar similares, tales como `memmem`. Utilizamos estas funciones en ocasiones. Estas funciones no existen en `namespace std`.
|
||||
|
||||
Si usted escribe `std::memcpy` en lugar de `memcpy` en todas partes, entonces `memmem` sin `std::` se verá extraño.
|
||||
|
||||
Sin embargo, todavía puedes usar `std::` si lo prefieres.
|
||||
|
||||
**3.** Usar funciones de C cuando las mismas están disponibles en la biblioteca estándar de C ++.
|
||||
|
||||
Esto es aceptable si es más eficiente.
|
||||
|
||||
Por ejemplo, use `memcpy` en lugar de `std::copy` para copiar grandes trozos de memoria.
|
||||
|
||||
**4.** Argumentos de función multilínea.
|
||||
|
||||
Se permite cualquiera de los siguientes estilos de ajuste:
|
||||
|
||||
``` cpp
|
||||
function(
|
||||
T1 x1,
|
||||
T2 x2)
|
||||
```
|
||||
|
||||
``` cpp
|
||||
function(
|
||||
size_t left, size_t right,
|
||||
const & RangesInDataParts ranges,
|
||||
size_t limit)
|
||||
```
|
||||
|
||||
``` cpp
|
||||
function(size_t left, size_t right,
|
||||
const & RangesInDataParts ranges,
|
||||
size_t limit)
|
||||
```
|
||||
|
||||
``` cpp
|
||||
function(size_t left, size_t right,
|
||||
const & RangesInDataParts ranges,
|
||||
size_t limit)
|
||||
```
|
||||
|
||||
``` cpp
|
||||
function(
|
||||
size_t left,
|
||||
size_t right,
|
||||
const & RangesInDataParts ranges,
|
||||
size_t limit)
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/development/style/) <!--hide-->
|
@ -1 +0,0 @@
|
||||
../../en/development/tests.md
|
@ -1,17 +0,0 @@
|
||||
---
|
||||
toc_priority: 32
|
||||
toc_title: Atomic
|
||||
---
|
||||
|
||||
|
||||
# Atomic {#atomic}
|
||||
|
||||
It is supports non-blocking `DROP` and `RENAME TABLE` queries and atomic `EXCHANGE TABLES t1 AND t2` queries. Atomic database engine is used by default.
|
||||
|
||||
## Creating a Database {#creating-a-database}
|
||||
|
||||
```sql
|
||||
CREATE DATABASE test ENGINE = Atomic;
|
||||
```
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/engines/database_engines/atomic/) <!--hide-->
|
@ -1,21 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Motores de base de datos
|
||||
toc_priority: 27
|
||||
toc_title: "Implantaci\xF3n"
|
||||
---
|
||||
|
||||
# Motores de base de datos {#database-engines}
|
||||
|
||||
Los motores de bases de datos le permiten trabajar con tablas.
|
||||
|
||||
De forma predeterminada, ClickHouse utiliza su motor de base de datos nativa, que proporciona [motores de mesa](../../engines/table-engines/index.md) y una [Dialecto SQL](../../sql-reference/syntax.md).
|
||||
|
||||
También puede utilizar los siguientes motores de base de datos:
|
||||
|
||||
- [MySQL](mysql.md)
|
||||
|
||||
- [Perezoso](lazy.md)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/database_engines/) <!--hide-->
|
@ -1,18 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 31
|
||||
toc_title: Perezoso
|
||||
---
|
||||
|
||||
# Perezoso {#lazy}
|
||||
|
||||
Mantiene las tablas en RAM solamente `expiration_time_in_seconds` segundos después del último acceso. Solo se puede usar con tablas \*Log.
|
||||
|
||||
Está optimizado para almacenar muchas tablas pequeñas \* Log, para las cuales hay un largo intervalo de tiempo entre los accesos.
|
||||
|
||||
## Creación de una base de datos {#creating-a-database}
|
||||
|
||||
CREATE DATABASE testlazy ENGINE = Lazy(expiration_time_in_seconds);
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/database_engines/lazy/) <!--hide-->
|
@ -1,135 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 30
|
||||
toc_title: MySQL
|
||||
---
|
||||
|
||||
# MySQL {#mysql}
|
||||
|
||||
Permite conectarse a bases de datos en un servidor MySQL remoto y realizar `INSERT` y `SELECT` consultas para intercambiar datos entre ClickHouse y MySQL.
|
||||
|
||||
El `MySQL` motor de base de datos traducir consultas al servidor MySQL para que pueda realizar operaciones tales como `SHOW TABLES` o `SHOW CREATE TABLE`.
|
||||
|
||||
No puede realizar las siguientes consultas:
|
||||
|
||||
- `RENAME`
|
||||
- `CREATE TABLE`
|
||||
- `ALTER`
|
||||
|
||||
## Creación de una base de datos {#creating-a-database}
|
||||
|
||||
``` sql
|
||||
CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster]
|
||||
ENGINE = MySQL('host:port', ['database' | database], 'user', 'password')
|
||||
```
|
||||
|
||||
**Parámetros del motor**
|
||||
|
||||
- `host:port` — MySQL server address.
|
||||
- `database` — Remote database name.
|
||||
- `user` — MySQL user.
|
||||
- `password` — User password.
|
||||
|
||||
## Soporte de tipos de datos {#data_types-support}
|
||||
|
||||
| MySQL | Haga clic en Casa |
|
||||
|----------------------------------|--------------------------------------------------------------|
|
||||
| UNSIGNED TINYINT | [UInt8](../../sql-reference/data-types/int-uint.md) |
|
||||
| TINYINT | [Int8](../../sql-reference/data-types/int-uint.md) |
|
||||
| UNSIGNED SMALLINT | [UInt16](../../sql-reference/data-types/int-uint.md) |
|
||||
| SMALLINT | [Int16](../../sql-reference/data-types/int-uint.md) |
|
||||
| UNSIGNED INT, UNSIGNED MEDIUMINT | [UInt32](../../sql-reference/data-types/int-uint.md) |
|
||||
| INT, MEDIUMINT | [Int32](../../sql-reference/data-types/int-uint.md) |
|
||||
| UNSIGNED BIGINT | [UInt64](../../sql-reference/data-types/int-uint.md) |
|
||||
| BIGINT | [Int64](../../sql-reference/data-types/int-uint.md) |
|
||||
| FLOAT | [Float32](../../sql-reference/data-types/float.md) |
|
||||
| DOUBLE | [Float64](../../sql-reference/data-types/float.md) |
|
||||
| DATE | [Fecha](../../sql-reference/data-types/date.md) |
|
||||
| DATETIME, TIMESTAMP | [FechaHora](../../sql-reference/data-types/datetime.md) |
|
||||
| BINARY | [Cadena fija](../../sql-reference/data-types/fixedstring.md) |
|
||||
|
||||
Todos los demás tipos de datos MySQL se convierten en [Cadena](../../sql-reference/data-types/string.md).
|
||||
|
||||
[NULL](../../sql-reference/data-types/nullable.md) se admite.
|
||||
|
||||
## Ejemplos de uso {#examples-of-use}
|
||||
|
||||
Tabla en MySQL:
|
||||
|
||||
``` text
|
||||
mysql> USE test;
|
||||
Database changed
|
||||
|
||||
mysql> CREATE TABLE `mysql_table` (
|
||||
-> `int_id` INT NOT NULL AUTO_INCREMENT,
|
||||
-> `float` FLOAT NOT NULL,
|
||||
-> PRIMARY KEY (`int_id`));
|
||||
Query OK, 0 rows affected (0,09 sec)
|
||||
|
||||
mysql> insert into mysql_table (`int_id`, `float`) VALUES (1,2);
|
||||
Query OK, 1 row affected (0,00 sec)
|
||||
|
||||
mysql> select * from mysql_table;
|
||||
+------+-----+
|
||||
| int_id | value |
|
||||
+------+-----+
|
||||
| 1 | 2 |
|
||||
+------+-----+
|
||||
1 row in set (0,00 sec)
|
||||
```
|
||||
|
||||
Base de datos en ClickHouse, intercambiando datos con el servidor MySQL:
|
||||
|
||||
``` sql
|
||||
CREATE DATABASE mysql_db ENGINE = MySQL('localhost:3306', 'test', 'my_user', 'user_password')
|
||||
```
|
||||
|
||||
``` sql
|
||||
SHOW DATABASES
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─name─────┐
|
||||
│ default │
|
||||
│ mysql_db │
|
||||
│ system │
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
SHOW TABLES FROM mysql_db
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─name─────────┐
|
||||
│ mysql_table │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT * FROM mysql_db.mysql_table
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─int_id─┬─value─┐
|
||||
│ 1 │ 2 │
|
||||
└────────┴───────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
INSERT INTO mysql_db.mysql_table VALUES (3,4)
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT * FROM mysql_db.mysql_table
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─int_id─┬─value─┐
|
||||
│ 1 │ 2 │
|
||||
│ 3 │ 4 │
|
||||
└────────┴───────┘
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/database_engines/mysql/) <!--hide-->
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Motor
|
||||
toc_priority: 25
|
||||
---
|
||||
|
||||
|
@ -1,85 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Motores de mesa
|
||||
toc_priority: 26
|
||||
toc_title: "Implantaci\xF3n"
|
||||
---
|
||||
|
||||
# Motores de mesa {#table_engines}
|
||||
|
||||
El motor de tabla (tipo de tabla) determina:
|
||||
|
||||
- Cómo y dónde se almacenan los datos, dónde escribirlos y dónde leerlos.
|
||||
- Qué consultas son compatibles y cómo.
|
||||
- Acceso a datos simultáneos.
|
||||
- Uso de índices, si está presente.
|
||||
- Si es posible la ejecución de solicitudes multiproceso.
|
||||
- Parámetros de replicación de datos.
|
||||
|
||||
## Familias de motores {#engine-families}
|
||||
|
||||
### Método de codificación de datos: {#mergetree}
|
||||
|
||||
Los motores de mesa más universales y funcionales para tareas de alta carga. La propiedad compartida por estos motores es la inserción rápida de datos con el posterior procesamiento de datos en segundo plano. `MergeTree` Los motores familiares admiten la replicación de datos (con [Replicado\*](mergetree-family/replication.md#table_engines-replication) versiones de motores), particionamiento y otras características no admitidas en otros motores.
|
||||
|
||||
Motores en la familia:
|
||||
|
||||
- [Método de codificación de datos:](mergetree-family/mergetree.md#mergetree)
|
||||
- [ReplacingMergeTree](mergetree-family/replacingmergetree.md#replacingmergetree)
|
||||
- [SummingMergeTree](mergetree-family/summingmergetree.md#summingmergetree)
|
||||
- [AgregaciónMergeTree](mergetree-family/aggregatingmergetree.md#aggregatingmergetree)
|
||||
- [ColapsarMergeTree](mergetree-family/collapsingmergetree.md#table_engine-collapsingmergetree)
|
||||
- [VersionedCollapsingMergeTree](mergetree-family/versionedcollapsingmergetree.md#versionedcollapsingmergetree)
|
||||
- [GraphiteMergeTree](mergetree-family/graphitemergetree.md#graphitemergetree)
|
||||
|
||||
### Registro {#log}
|
||||
|
||||
Ligero [motor](log-family/index.md) con funcionalidad mínima. Son los más efectivos cuando necesita escribir rápidamente muchas tablas pequeñas (hasta aproximadamente 1 millón de filas) y leerlas más tarde como un todo.
|
||||
|
||||
Motores en la familia:
|
||||
|
||||
- [TinyLog](log-family/tinylog.md#tinylog)
|
||||
- [StripeLog](log-family/stripelog.md#stripelog)
|
||||
- [Registro](log-family/log.md#log)
|
||||
|
||||
### Motores de integración {#integration-engines}
|
||||
|
||||
Motores para comunicarse con otros sistemas de almacenamiento y procesamiento de datos.
|
||||
|
||||
Motores en la familia:
|
||||
|
||||
- [Kafka](integrations/kafka.md#kafka)
|
||||
- [MySQL](integrations/mysql.md#mysql)
|
||||
- [ODBC](integrations/odbc.md#table-engine-odbc)
|
||||
- [JDBC](integrations/jdbc.md#table-engine-jdbc)
|
||||
- [HDFS](integrations/hdfs.md#hdfs)
|
||||
|
||||
### Motores especiales {#special-engines}
|
||||
|
||||
Motores en la familia:
|
||||
|
||||
- [Distribuido](special/distributed.md#distributed)
|
||||
- [Método de codificación de datos:](special/materializedview.md#materializedview)
|
||||
- [Diccionario](special/dictionary.md#dictionary)
|
||||
- \[Fusión\](special/merge.md#merge
|
||||
- [File](special/file.md#file)
|
||||
- [Nulo](special/null.md#null)
|
||||
- [Establecer](special/set.md#set)
|
||||
- [Unir](special/join.md#join)
|
||||
- [URL](special/url.md#table_engines-url)
|
||||
- [Vista](special/view.md#table_engines-view)
|
||||
- [Memoria](special/memory.md#memory)
|
||||
- [Búfer](special/buffer.md#buffer)
|
||||
|
||||
## Virtual Columnas {#table_engines-virtual_columns}
|
||||
|
||||
La columna virtual es un atributo de motor de tabla integral que se define en el código fuente del motor.
|
||||
|
||||
No debe especificar columnas virtuales en el `CREATE TABLE` consulta y no puedes verlos en `SHOW CREATE TABLE` y `DESCRIBE TABLE` resultados de la consulta. Las columnas virtuales también son de solo lectura, por lo que no puede insertar datos en columnas virtuales.
|
||||
|
||||
Para seleccionar datos de una columna virtual, debe especificar su nombre en el `SELECT` consulta. `SELECT *` no devuelve valores de columnas virtuales.
|
||||
|
||||
Si crea una tabla con una columna que tiene el mismo nombre que una de las columnas virtuales de la tabla, la columna virtual se vuelve inaccesible. No recomendamos hacer esto. Para ayudar a evitar conflictos, los nombres de columna virtual suelen tener el prefijo de un guión bajo.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/) <!--hide-->
|
@ -1,123 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 36
|
||||
toc_title: HDFS
|
||||
---
|
||||
|
||||
# HDFS {#table_engines-hdfs}
|
||||
|
||||
Este motor proporciona integración con [Acerca de nosotros](https://en.wikipedia.org/wiki/Apache_Hadoop) permitiendo gestionar datos sobre [HDFS](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html)a través de ClickHouse. Este motor es similar
|
||||
a la [File](../special/file.md#table_engines-file) y [URL](../special/url.md#table_engines-url) motores, pero proporciona características específicas de Hadoop.
|
||||
|
||||
## Uso {#usage}
|
||||
|
||||
``` sql
|
||||
ENGINE = HDFS(URI, format)
|
||||
```
|
||||
|
||||
El `URI` El parámetro es el URI del archivo completo en HDFS.
|
||||
El `format` parámetro especifica uno de los formatos de archivo disponibles. Realizar
|
||||
`SELECT` consultas, el formato debe ser compatible para la entrada, y para realizar
|
||||
`INSERT` queries – for output. The available formats are listed in the
|
||||
[Formato](../../../interfaces/formats.md#formats) apartado.
|
||||
La parte de la ruta de `URI` puede contener globs. En este caso, la tabla sería de solo lectura.
|
||||
|
||||
**Ejemplo:**
|
||||
|
||||
**1.** Configurar el `hdfs_engine_table` tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE hdfs_engine_table (name String, value UInt32) ENGINE=HDFS('hdfs://hdfs1:9000/other_storage', 'TSV')
|
||||
```
|
||||
|
||||
**2.** Llenar archivo:
|
||||
|
||||
``` sql
|
||||
INSERT INTO hdfs_engine_table VALUES ('one', 1), ('two', 2), ('three', 3)
|
||||
```
|
||||
|
||||
**3.** Consultar los datos:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM hdfs_engine_table LIMIT 2
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─name─┬─value─┐
|
||||
│ one │ 1 │
|
||||
│ two │ 2 │
|
||||
└──────┴───────┘
|
||||
```
|
||||
|
||||
## Detalles de implementación {#implementation-details}
|
||||
|
||||
- Las lecturas y escrituras pueden ser paralelas
|
||||
- No soportado:
|
||||
- `ALTER` y `SELECT...SAMPLE` operación.
|
||||
- Índices.
|
||||
- Replicación.
|
||||
|
||||
**Globs en el camino**
|
||||
|
||||
Múltiples componentes de ruta de acceso pueden tener globs. Para ser procesado, el archivo debe existir y coincidir con todo el patrón de ruta. Listado de archivos determina durante `SELECT` (no en `CREATE` momento).
|
||||
|
||||
- `*` — Substitutes any number of any characters except `/` incluyendo cadena vacía.
|
||||
- `?` — Substitutes any single character.
|
||||
- `{some_string,another_string,yet_another_one}` — Substitutes any of strings `'some_string', 'another_string', 'yet_another_one'`.
|
||||
- `{N..M}` — Substitutes any number in range from N to M including both borders.
|
||||
|
||||
Construcciones con `{}` son similares a la [remoto](../../../sql-reference/table-functions/remote.md) función de la tabla.
|
||||
|
||||
**Ejemplo**
|
||||
|
||||
1. Supongamos que tenemos varios archivos en formato TSV con los siguientes URI en HDFS:
|
||||
|
||||
- ‘hdfs://hdfs1:9000/some_dir/some_file_1’
|
||||
- ‘hdfs://hdfs1:9000/some_dir/some_file_2’
|
||||
- ‘hdfs://hdfs1:9000/some_dir/some_file_3’
|
||||
- ‘hdfs://hdfs1:9000/another_dir/some_file_1’
|
||||
- ‘hdfs://hdfs1:9000/another_dir/some_file_2’
|
||||
- ‘hdfs://hdfs1:9000/another_dir/some_file_3’
|
||||
|
||||
1. Hay varias maneras de hacer una tabla que consta de los seis archivos:
|
||||
|
||||
<!-- -->
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_with_range (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/{some,another}_dir/some_file_{1..3}', 'TSV')
|
||||
```
|
||||
|
||||
Otra forma:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_with_question_mark (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/{some,another}_dir/some_file_?', 'TSV')
|
||||
```
|
||||
|
||||
La tabla consta de todos los archivos en ambos directorios (todos los archivos deben satisfacer el formato y el esquema descritos en la consulta):
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_with_asterisk (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/{some,another}_dir/*', 'TSV')
|
||||
```
|
||||
|
||||
!!! warning "Advertencia"
|
||||
Si la lista de archivos contiene rangos de números con ceros a la izquierda, use la construcción con llaves para cada dígito por separado o use `?`.
|
||||
|
||||
**Ejemplo**
|
||||
|
||||
Crear tabla con archivos llamados `file000`, `file001`, … , `file999`:
|
||||
|
||||
``` sql
|
||||
CREARE TABLE big_table (name String, value UInt32) ENGINE = HDFS('hdfs://hdfs1:9000/big_dir/file{0..9}{0..9}{0..9}', 'CSV')
|
||||
```
|
||||
|
||||
## Virtual Columnas {#virtual-columns}
|
||||
|
||||
- `_path` — Path to the file.
|
||||
- `_file` — Name of the file.
|
||||
|
||||
**Ver también**
|
||||
|
||||
- [Virtual columnas](../index.md#table_engines-virtual_columns)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/hdfs/) <!--hide-->
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: "Integraci\xF3n"
|
||||
toc_priority: 30
|
||||
---
|
||||
|
||||
|
@ -1,90 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 34
|
||||
toc_title: JDBC
|
||||
---
|
||||
|
||||
# JDBC {#table-engine-jdbc}
|
||||
|
||||
Permite que ClickHouse se conecte a bases de datos externas a través de [JDBC](https://en.wikipedia.org/wiki/Java_Database_Connectivity).
|
||||
|
||||
Para implementar la conexión JDBC, ClickHouse utiliza el programa independiente [Sistema abierto.](https://github.com/alex-krash/clickhouse-jdbc-bridge) que debería ejecutarse como un demonio.
|
||||
|
||||
Este motor soporta el [NULL](../../../sql-reference/data-types/nullable.md) tipo de datos.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name
|
||||
(
|
||||
columns list...
|
||||
)
|
||||
ENGINE = JDBC(dbms_uri, external_database, external_table)
|
||||
```
|
||||
|
||||
**Parámetros del motor**
|
||||
|
||||
- `dbms_uri` — URI of an external DBMS.
|
||||
|
||||
Formato: `jdbc:<driver_name>://<host_name>:<port>/?user=<username>&password=<password>`.
|
||||
Ejemplo para MySQL: `jdbc:mysql://localhost:3306/?user=root&password=root`.
|
||||
|
||||
- `external_database` — Database in an external DBMS.
|
||||
|
||||
- `external_table` — Name of the table in `external_database`.
|
||||
|
||||
## Ejemplo de uso {#usage-example}
|
||||
|
||||
Crear una tabla en el servidor MySQL conectándose directamente con su cliente de consola:
|
||||
|
||||
``` text
|
||||
mysql> CREATE TABLE `test`.`test` (
|
||||
-> `int_id` INT NOT NULL AUTO_INCREMENT,
|
||||
-> `int_nullable` INT NULL DEFAULT NULL,
|
||||
-> `float` FLOAT NOT NULL,
|
||||
-> `float_nullable` FLOAT NULL DEFAULT NULL,
|
||||
-> PRIMARY KEY (`int_id`));
|
||||
Query OK, 0 rows affected (0,09 sec)
|
||||
|
||||
mysql> insert into test (`int_id`, `float`) VALUES (1,2);
|
||||
Query OK, 1 row affected (0,00 sec)
|
||||
|
||||
mysql> select * from test;
|
||||
+------+----------+-----+----------+
|
||||
| int_id | int_nullable | float | float_nullable |
|
||||
+------+----------+-----+----------+
|
||||
| 1 | NULL | 2 | NULL |
|
||||
+------+----------+-----+----------+
|
||||
1 row in set (0,00 sec)
|
||||
```
|
||||
|
||||
Creación de una tabla en el servidor ClickHouse y selección de datos de ella:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE jdbc_table
|
||||
(
|
||||
`int_id` Int32,
|
||||
`int_nullable` Nullable(Int32),
|
||||
`float` Float32,
|
||||
`float_nullable` Nullable(Float32)
|
||||
)
|
||||
ENGINE JDBC('jdbc:mysql://localhost:3306/?user=root&password=root', 'test', 'test')
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT *
|
||||
FROM jdbc_table
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─int_id─┬─int_nullable─┬─float─┬─float_nullable─┐
|
||||
│ 1 │ ᴺᵁᴸᴸ │ 2 │ ᴺᵁᴸᴸ │
|
||||
└────────┴──────────────┴───────┴────────────────┘
|
||||
```
|
||||
|
||||
## Ver también {#see-also}
|
||||
|
||||
- [Función de la tabla de JDBC](../../../sql-reference/table-functions/jdbc.md).
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/jdbc/) <!--hide-->
|
@ -1,180 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 32
|
||||
toc_title: Kafka
|
||||
---
|
||||
|
||||
# Kafka {#kafka}
|
||||
|
||||
Este motor funciona con [Acerca de nosotros](http://kafka.apache.org/).
|
||||
|
||||
Kafka te permite:
|
||||
|
||||
- Publicar o suscribirse a flujos de datos.
|
||||
- Organice el almacenamiento tolerante a fallos.
|
||||
- Secuencias de proceso a medida que estén disponibles.
|
||||
|
||||
## Creación de una tabla {#table_engine-kafka-creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = Kafka()
|
||||
SETTINGS
|
||||
kafka_broker_list = 'host:port',
|
||||
kafka_topic_list = 'topic1,topic2,...',
|
||||
kafka_group_name = 'group_name',
|
||||
kafka_format = 'data_format'[,]
|
||||
[kafka_row_delimiter = 'delimiter_symbol',]
|
||||
[kafka_schema = '',]
|
||||
[kafka_num_consumers = N,]
|
||||
[kafka_max_block_size = 0,]
|
||||
[kafka_skip_broken_messages = N,]
|
||||
[kafka_commit_every_batch = 0]
|
||||
```
|
||||
|
||||
Parámetros requeridos:
|
||||
|
||||
- `kafka_broker_list` – A comma-separated list of brokers (for example, `localhost:9092`).
|
||||
- `kafka_topic_list` – A list of Kafka topics.
|
||||
- `kafka_group_name` – A group of Kafka consumers. Reading margins are tracked for each group separately. If you don't want messages to be duplicated in the cluster, use the same group name everywhere.
|
||||
- `kafka_format` – Message format. Uses the same notation as the SQL `FORMAT` función, tal como `JSONEachRow`. Para obtener más información, consulte [Formato](../../../interfaces/formats.md) apartado.
|
||||
|
||||
Parámetros opcionales:
|
||||
|
||||
- `kafka_row_delimiter` – Delimiter character, which ends the message.
|
||||
- `kafka_schema` – Parameter that must be used if the format requires a schema definition. For example, [Cap'n Proto](https://capnproto.org/) requiere la ruta de acceso al archivo de esquema y el nombre de la raíz `schema.capnp:Message` objeto.
|
||||
- `kafka_num_consumers` – The number of consumers per table. Default: `1`. Especifique más consumidores si el rendimiento de un consumidor es insuficiente. El número total de consumidores no debe exceder el número de particiones en el tema, ya que solo se puede asignar un consumidor por partición.
|
||||
- `kafka_max_block_size` - El tamaño máximo de lote (en mensajes) para la encuesta (predeterminado: `max_block_size`).
|
||||
- `kafka_skip_broken_messages` – Kafka message parser tolerance to schema-incompatible messages per block. Default: `0`. Si `kafka_skip_broken_messages = N` entonces el motor salta *N* Mensajes de Kafka que no se pueden analizar (un mensaje es igual a una fila de datos).
|
||||
- `kafka_commit_every_batch` - Confirmar cada lote consumido y manejado en lugar de una única confirmación después de escribir un bloque completo (predeterminado: `0`).
|
||||
|
||||
Ejemplos:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE queue (
|
||||
timestamp UInt64,
|
||||
level String,
|
||||
message String
|
||||
) ENGINE = Kafka('localhost:9092', 'topic', 'group1', 'JSONEachRow');
|
||||
|
||||
SELECT * FROM queue LIMIT 5;
|
||||
|
||||
CREATE TABLE queue2 (
|
||||
timestamp UInt64,
|
||||
level String,
|
||||
message String
|
||||
) ENGINE = Kafka SETTINGS kafka_broker_list = 'localhost:9092',
|
||||
kafka_topic_list = 'topic',
|
||||
kafka_group_name = 'group1',
|
||||
kafka_format = 'JSONEachRow',
|
||||
kafka_num_consumers = 4;
|
||||
|
||||
CREATE TABLE queue2 (
|
||||
timestamp UInt64,
|
||||
level String,
|
||||
message String
|
||||
) ENGINE = Kafka('localhost:9092', 'topic', 'group1')
|
||||
SETTINGS kafka_format = 'JSONEachRow',
|
||||
kafka_num_consumers = 4;
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No utilice este método en nuevos proyectos. Si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
Kafka(kafka_broker_list, kafka_topic_list, kafka_group_name, kafka_format
|
||||
[, kafka_row_delimiter, kafka_schema, kafka_num_consumers, kafka_skip_broken_messages])
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Descripci {#description}
|
||||
|
||||
Los mensajes entregados se realizan un seguimiento automático, por lo que cada mensaje de un grupo solo se cuenta una vez. Si desea obtener los datos dos veces, cree una copia de la tabla con otro nombre de grupo.
|
||||
|
||||
Los grupos son flexibles y se sincronizan en el clúster. Por ejemplo, si tiene 10 temas y 5 copias de una tabla en un clúster, cada copia obtiene 2 temas. Si el número de copias cambia, los temas se redistribuyen automáticamente entre las copias. Lea más sobre esto en http://kafka.apache.org/intro .
|
||||
|
||||
`SELECT` no es particularmente útil para leer mensajes (excepto para la depuración), ya que cada mensaje se puede leer solo una vez. Es más práctico crear subprocesos en tiempo real utilizando vistas materializadas. Para hacer esto:
|
||||
|
||||
1. Use el motor para crear un consumidor de Kafka y considérelo como un flujo de datos.
|
||||
2. Crea una tabla con la estructura deseada.
|
||||
3. Cree una vista materializada que convierta los datos del motor y los coloque en una tabla creada previamente.
|
||||
|
||||
Cuando el `MATERIALIZED VIEW` se une al motor, comienza a recopilar datos en segundo plano. Esto le permite recibir continuamente mensajes de Kafka y convertirlos al formato requerido usando `SELECT`.
|
||||
Una tabla kafka puede tener tantas vistas materializadas como desee, no leen datos de la tabla kafka directamente, sino que reciben nuevos registros (en bloques), de esta manera puede escribir en varias tablas con diferentes niveles de detalle (con agrupación - agregación y sin).
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE queue (
|
||||
timestamp UInt64,
|
||||
level String,
|
||||
message String
|
||||
) ENGINE = Kafka('localhost:9092', 'topic', 'group1', 'JSONEachRow');
|
||||
|
||||
CREATE TABLE daily (
|
||||
day Date,
|
||||
level String,
|
||||
total UInt64
|
||||
) ENGINE = SummingMergeTree(day, (day, level), 8192);
|
||||
|
||||
CREATE MATERIALIZED VIEW consumer TO daily
|
||||
AS SELECT toDate(toDateTime(timestamp)) AS day, level, count() as total
|
||||
FROM queue GROUP BY day, level;
|
||||
|
||||
SELECT level, sum(total) FROM daily GROUP BY level;
|
||||
```
|
||||
|
||||
Para mejorar el rendimiento, los mensajes recibidos se agrupan en bloques del tamaño de [Max_insert_block_size](../../../operations/server-configuration-parameters/settings.md#settings-max_insert_block_size). Si el bloque no se formó dentro de [Nombre de la red inalámbrica (SSID):](../../../operations/server-configuration-parameters/settings.md) milisegundos, los datos se vaciarán a la tabla independientemente de la integridad del bloque.
|
||||
|
||||
Para detener la recepción de datos de tema o cambiar la lógica de conversión, desconecte la vista materializada:
|
||||
|
||||
``` sql
|
||||
DETACH TABLE consumer;
|
||||
ATTACH TABLE consumer;
|
||||
```
|
||||
|
||||
Si desea cambiar la tabla de destino utilizando `ALTER`, recomendamos deshabilitar la vista de material para evitar discrepancias entre la tabla de destino y los datos de la vista.
|
||||
|
||||
## Configuración {#configuration}
|
||||
|
||||
Similar a GraphiteMergeTree, el motor Kafka admite una configuración extendida utilizando el archivo de configuración ClickHouse. Hay dos claves de configuración que puede usar: global (`kafka`) y a nivel de tema (`kafka_*`). La configuración global se aplica primero y, a continuación, se aplica la configuración de nivel de tema (si existe).
|
||||
|
||||
``` xml
|
||||
<!-- Global configuration options for all tables of Kafka engine type -->
|
||||
<kafka>
|
||||
<debug>cgrp</debug>
|
||||
<auto_offset_reset>smallest</auto_offset_reset>
|
||||
</kafka>
|
||||
|
||||
<!-- Configuration specific for topic "logs" -->
|
||||
<kafka_logs>
|
||||
<retry_backoff_ms>250</retry_backoff_ms>
|
||||
<fetch_min_bytes>100000</fetch_min_bytes>
|
||||
</kafka_logs>
|
||||
```
|
||||
|
||||
Para obtener una lista de posibles opciones de configuración, consulte [referencia de configuración librdkafka](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md). Usa el guión bajo (`_`) en lugar de un punto en la configuración de ClickHouse. Por ejemplo, `check.crcs=true` será `<check_crcs>true</check_crcs>`.
|
||||
|
||||
## Virtual Columnas {#virtual-columns}
|
||||
|
||||
- `_topic` — Kafka topic.
|
||||
- `_key` — Key of the message.
|
||||
- `_offset` — Offset of the message.
|
||||
- `_timestamp` — Timestamp of the message.
|
||||
- `_partition` — Partition of Kafka topic.
|
||||
|
||||
**Ver también**
|
||||
|
||||
- [Virtual columnas](../index.md#table_engines-virtual_columns)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/kafka/) <!--hide-->
|
@ -1,105 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 33
|
||||
toc_title: MySQL
|
||||
---
|
||||
|
||||
# Mysql {#mysql}
|
||||
|
||||
El motor MySQL le permite realizar `SELECT` consultas sobre datos almacenados en un servidor MySQL remoto.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
|
||||
...
|
||||
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']);
|
||||
```
|
||||
|
||||
Vea una descripción detallada del [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) consulta.
|
||||
|
||||
La estructura de la tabla puede diferir de la estructura de la tabla MySQL original:
|
||||
|
||||
- Los nombres de columna deben ser los mismos que en la tabla MySQL original, pero puede usar solo algunas de estas columnas y en cualquier orden.
|
||||
- Los tipos de columna pueden diferir de los de la tabla MySQL original. ClickHouse intenta [elenco](../../../sql-reference/functions/type-conversion-functions.md#type_conversion_function-cast) valores a los tipos de datos ClickHouse.
|
||||
|
||||
**Parámetros del motor**
|
||||
|
||||
- `host:port` — MySQL server address.
|
||||
|
||||
- `database` — Remote database name.
|
||||
|
||||
- `table` — Remote table name.
|
||||
|
||||
- `user` — MySQL user.
|
||||
|
||||
- `password` — User password.
|
||||
|
||||
- `replace_query` — Flag that converts `INSERT INTO` consultas a `REPLACE INTO`. Si `replace_query=1`, la consulta se sustituye.
|
||||
|
||||
- `on_duplicate_clause` — The `ON DUPLICATE KEY on_duplicate_clause` expresión que se añade a la `INSERT` consulta.
|
||||
|
||||
Ejemplo: `INSERT INTO t (c1,c2) VALUES ('a', 2) ON DUPLICATE KEY UPDATE c2 = c2 + 1`, donde `on_duplicate_clause` ser `UPDATE c2 = c2 + 1`. Ver el [Documentación de MySQL](https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html) para encontrar qué `on_duplicate_clause` se puede utilizar con el `ON DUPLICATE KEY` clausula.
|
||||
|
||||
Especificar `on_duplicate_clause` tienes que pasar `0` a la `replace_query` parámetro. Si pasa simultáneamente `replace_query = 1` y `on_duplicate_clause`, ClickHouse genera una excepción.
|
||||
|
||||
Simple `WHERE` cláusulas tales como `=, !=, >, >=, <, <=` se ejecutan en el servidor MySQL.
|
||||
|
||||
El resto de las condiciones y el `LIMIT` La restricción de muestreo se ejecuta en ClickHouse solo después de que finalice la consulta a MySQL.
|
||||
|
||||
## Ejemplo de uso {#usage-example}
|
||||
|
||||
Tabla en MySQL:
|
||||
|
||||
``` text
|
||||
mysql> CREATE TABLE `test`.`test` (
|
||||
-> `int_id` INT NOT NULL AUTO_INCREMENT,
|
||||
-> `int_nullable` INT NULL DEFAULT NULL,
|
||||
-> `float` FLOAT NOT NULL,
|
||||
-> `float_nullable` FLOAT NULL DEFAULT NULL,
|
||||
-> PRIMARY KEY (`int_id`));
|
||||
Query OK, 0 rows affected (0,09 sec)
|
||||
|
||||
mysql> insert into test (`int_id`, `float`) VALUES (1,2);
|
||||
Query OK, 1 row affected (0,00 sec)
|
||||
|
||||
mysql> select * from test;
|
||||
+------+----------+-----+----------+
|
||||
| int_id | int_nullable | float | float_nullable |
|
||||
+------+----------+-----+----------+
|
||||
| 1 | NULL | 2 | NULL |
|
||||
+------+----------+-----+----------+
|
||||
1 row in set (0,00 sec)
|
||||
```
|
||||
|
||||
Tabla en ClickHouse, recuperando datos de la tabla MySQL creada anteriormente:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE mysql_table
|
||||
(
|
||||
`float_nullable` Nullable(Float32),
|
||||
`int_id` Int32
|
||||
)
|
||||
ENGINE = MySQL('localhost:3306', 'test', 'test', 'bayonet', '123')
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT * FROM mysql_table
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─float_nullable─┬─int_id─┐
|
||||
│ ᴺᵁᴸᴸ │ 1 │
|
||||
└────────────────┴────────┘
|
||||
```
|
||||
|
||||
## Ver también {#see-also}
|
||||
|
||||
- [El ‘mysql’ función de la tabla](../../../sql-reference/table-functions/mysql.md)
|
||||
- [Uso de MySQL como fuente de diccionario externo](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md#dicts-external_dicts_dict_sources-mysql)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/mysql/) <!--hide-->
|
@ -1,132 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 35
|
||||
toc_title: ODBC
|
||||
---
|
||||
|
||||
# ODBC {#table-engine-odbc}
|
||||
|
||||
Permite que ClickHouse se conecte a bases de datos externas a través de [ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity).
|
||||
|
||||
Para implementar con seguridad conexiones ODBC, ClickHouse usa un programa separado `clickhouse-odbc-bridge`. Si el controlador ODBC se carga directamente desde `clickhouse-server`, problemas de controlador pueden bloquear el servidor ClickHouse. ClickHouse se inicia automáticamente `clickhouse-odbc-bridge` cuando se requiere. El programa de puente ODBC se instala desde el mismo paquete que el `clickhouse-server`.
|
||||
|
||||
Este motor soporta el [NULL](../../../sql-reference/data-types/nullable.md) tipo de datos.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1],
|
||||
name2 [type2],
|
||||
...
|
||||
)
|
||||
ENGINE = ODBC(connection_settings, external_database, external_table)
|
||||
```
|
||||
|
||||
Vea una descripción detallada del [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) consulta.
|
||||
|
||||
La estructura de la tabla puede diferir de la estructura de la tabla de origen:
|
||||
|
||||
- Los nombres de columna deben ser los mismos que en la tabla de origen, pero puede usar solo algunas de estas columnas y en cualquier orden.
|
||||
- Los tipos de columna pueden diferir de los de la tabla de origen. ClickHouse intenta [elenco](../../../sql-reference/functions/type-conversion-functions.md#type_conversion_function-cast) valores a los tipos de datos ClickHouse.
|
||||
|
||||
**Parámetros del motor**
|
||||
|
||||
- `connection_settings` — Name of the section with connection settings in the `odbc.ini` file.
|
||||
- `external_database` — Name of a database in an external DBMS.
|
||||
- `external_table` — Name of a table in the `external_database`.
|
||||
|
||||
## Ejemplo de uso {#usage-example}
|
||||
|
||||
**Recuperación de datos de la instalación local de MySQL a través de ODBC**
|
||||
|
||||
Este ejemplo se comprueba para Ubuntu Linux 18.04 y el servidor MySQL 5.7.
|
||||
|
||||
Asegúrese de que unixODBC y MySQL Connector están instalados.
|
||||
|
||||
De forma predeterminada (si se instala desde paquetes), ClickHouse comienza como usuario `clickhouse`. Por lo tanto, debe crear y configurar este usuario en el servidor MySQL.
|
||||
|
||||
``` bash
|
||||
$ sudo mysql
|
||||
```
|
||||
|
||||
``` sql
|
||||
mysql> CREATE USER 'clickhouse'@'localhost' IDENTIFIED BY 'clickhouse';
|
||||
mysql> GRANT ALL PRIVILEGES ON *.* TO 'clickhouse'@'clickhouse' WITH GRANT OPTION;
|
||||
```
|
||||
|
||||
A continuación, configure la conexión en `/etc/odbc.ini`.
|
||||
|
||||
``` bash
|
||||
$ cat /etc/odbc.ini
|
||||
[mysqlconn]
|
||||
DRIVER = /usr/local/lib/libmyodbc5w.so
|
||||
SERVER = 127.0.0.1
|
||||
PORT = 3306
|
||||
DATABASE = test
|
||||
USERNAME = clickhouse
|
||||
PASSWORD = clickhouse
|
||||
```
|
||||
|
||||
Puede verificar la conexión usando el `isql` utilidad desde la instalación de unixODBC.
|
||||
|
||||
``` bash
|
||||
$ isql -v mysqlconn
|
||||
+-------------------------+
|
||||
| Connected! |
|
||||
| |
|
||||
...
|
||||
```
|
||||
|
||||
Tabla en MySQL:
|
||||
|
||||
``` text
|
||||
mysql> CREATE TABLE `test`.`test` (
|
||||
-> `int_id` INT NOT NULL AUTO_INCREMENT,
|
||||
-> `int_nullable` INT NULL DEFAULT NULL,
|
||||
-> `float` FLOAT NOT NULL,
|
||||
-> `float_nullable` FLOAT NULL DEFAULT NULL,
|
||||
-> PRIMARY KEY (`int_id`));
|
||||
Query OK, 0 rows affected (0,09 sec)
|
||||
|
||||
mysql> insert into test (`int_id`, `float`) VALUES (1,2);
|
||||
Query OK, 1 row affected (0,00 sec)
|
||||
|
||||
mysql> select * from test;
|
||||
+------+----------+-----+----------+
|
||||
| int_id | int_nullable | float | float_nullable |
|
||||
+------+----------+-----+----------+
|
||||
| 1 | NULL | 2 | NULL |
|
||||
+------+----------+-----+----------+
|
||||
1 row in set (0,00 sec)
|
||||
```
|
||||
|
||||
Tabla en ClickHouse, recuperando datos de la tabla MySQL:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE odbc_t
|
||||
(
|
||||
`int_id` Int32,
|
||||
`float_nullable` Nullable(Float32)
|
||||
)
|
||||
ENGINE = ODBC('DSN=mysqlconn', 'test', 'test')
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT * FROM odbc_t
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─int_id─┬─float_nullable─┐
|
||||
│ 1 │ ᴺᵁᴸᴸ │
|
||||
└────────┴────────────────┘
|
||||
```
|
||||
|
||||
## Ver también {#see-also}
|
||||
|
||||
- [Diccionarios externos ODBC](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-sources.md#dicts-external_dicts_dict_sources-odbc)
|
||||
- [Tabla ODBC función](../../../sql-reference/table-functions/odbc.md)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/odbc/) <!--hide-->
|
@ -1,47 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Familia de registro
|
||||
toc_priority: 29
|
||||
toc_title: "Implantaci\xF3n"
|
||||
---
|
||||
|
||||
# Familia del motor de registro {#log-engine-family}
|
||||
|
||||
Estos motores fueron desarrollados para escenarios en los que necesita escribir rápidamente muchas tablas pequeñas (hasta aproximadamente 1 millón de filas) y leerlas más tarde en su conjunto.
|
||||
|
||||
Motores de la familia:
|
||||
|
||||
- [StripeLog](stripelog.md)
|
||||
- [Registro](log.md)
|
||||
- [TinyLog](tinylog.md)
|
||||
|
||||
## Propiedades comunes {#common-properties}
|
||||
|
||||
Motor:
|
||||
|
||||
- Almacenar datos en un disco.
|
||||
|
||||
- Agregue datos al final del archivo al escribir.
|
||||
|
||||
- Bloqueos de soporte para el acceso a datos simultáneos.
|
||||
|
||||
Durante `INSERT` consultas, la tabla está bloqueada y otras consultas para leer y escribir datos esperan a que la tabla se desbloquee. Si no hay consultas de escritura de datos, se puede realizar cualquier número de consultas de lectura de datos simultáneamente.
|
||||
|
||||
- No apoyo [mutación](../../../sql-reference/statements/alter.md#alter-mutations) operación.
|
||||
|
||||
- No admite índices.
|
||||
|
||||
Esto significa que `SELECT` las consultas para rangos de datos no son eficientes.
|
||||
|
||||
- No escriba datos atómicamente.
|
||||
|
||||
Puede obtener una tabla con datos dañados si algo rompe la operación de escritura, por ejemplo, un cierre anormal del servidor.
|
||||
|
||||
## Diferencia {#differences}
|
||||
|
||||
El `TinyLog` es el más simple de la familia y proporciona la funcionalidad más pobre y la eficiencia más baja. El `TinyLog` el motor no admite la lectura de datos paralelos por varios hilos. Lee datos más lentamente que otros motores de la familia que admiten lectura paralela y utiliza casi tantos descriptores como los `Log` motor porque almacena cada columna en un archivo separado. Úselo en escenarios simples de baja carga.
|
||||
|
||||
El `Log` y `StripeLog` Los motores admiten lectura de datos paralela. Al leer datos, ClickHouse usa múltiples hilos. Cada subproceso procesa un bloque de datos separado. El `Log` utiliza un archivo separado para cada columna de la tabla. `StripeLog` almacena todos los datos en un archivo. Como resultado, el `StripeLog` el motor utiliza menos descriptores en el sistema operativo, pero el `Log` proporciona una mayor eficiencia al leer datos.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/log_family/) <!--hide-->
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 33
|
||||
toc_title: Registro
|
||||
---
|
||||
|
||||
# Registro {#log}
|
||||
|
||||
El motor pertenece a la familia de motores de registro. Consulte las propiedades comunes de los motores de registro y sus diferencias en [Familia del motor de registro](index.md) artículo.
|
||||
|
||||
El registro difiere de [TinyLog](tinylog.md) en que un pequeño archivo de “marks” reside con los archivos de columna. Estas marcas se escriben en cada bloque de datos y contienen compensaciones que indican dónde comenzar a leer el archivo para omitir el número especificado de filas. Esto hace posible leer datos de tabla en múltiples hilos.
|
||||
Para el acceso a datos simultáneos, las operaciones de lectura se pueden realizar simultáneamente, mientras que las operaciones de escritura bloquean las lecturas entre sí.
|
||||
El motor de registro no admite índices. Del mismo modo, si la escritura en una tabla falla, la tabla se rompe y la lectura de ella devuelve un error. El motor de registro es adecuado para datos temporales, tablas de escritura única y para fines de prueba o demostración.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/log/) <!--hide-->
|
@ -1,95 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 32
|
||||
toc_title: StripeLog
|
||||
---
|
||||
|
||||
# Lista de Stripelog {#stripelog}
|
||||
|
||||
Este motor pertenece a la familia de motores de registro. Consulte las propiedades comunes de los motores de registro y sus diferencias en [Familia del motor de registro](index.md) artículo.
|
||||
|
||||
Utilice este motor en escenarios en los que necesite escribir muchas tablas con una pequeña cantidad de datos (menos de 1 millón de filas).
|
||||
|
||||
## Creación de una tabla {#table_engines-stripelog-creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
column1_name [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
column2_name [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = StripeLog
|
||||
```
|
||||
|
||||
Vea la descripción detallada del [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) consulta.
|
||||
|
||||
## Escribir los datos {#table_engines-stripelog-writing-the-data}
|
||||
|
||||
El `StripeLog` el motor almacena todas las columnas en un archivo. Para cada `INSERT` consulta, ClickHouse agrega el bloque de datos al final de un archivo de tabla, escribiendo columnas una por una.
|
||||
|
||||
Para cada tabla, ClickHouse escribe los archivos:
|
||||
|
||||
- `data.bin` — Data file.
|
||||
- `index.mrk` — File with marks. Marks contain offsets for each column of each data block inserted.
|
||||
|
||||
El `StripeLog` el motor no soporta el `ALTER UPDATE` y `ALTER DELETE` operación.
|
||||
|
||||
## Lectura de los datos {#table_engines-stripelog-reading-the-data}
|
||||
|
||||
El archivo con marcas permite ClickHouse paralelizar la lectura de datos. Esto significa que un `SELECT` query devuelve filas en un orden impredecible. Utilice el `ORDER BY` cláusula para ordenar filas.
|
||||
|
||||
## Ejemplo de uso {#table_engines-stripelog-example-of-use}
|
||||
|
||||
Creación de una tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE stripe_log_table
|
||||
(
|
||||
timestamp DateTime,
|
||||
message_type String,
|
||||
message String
|
||||
)
|
||||
ENGINE = StripeLog
|
||||
```
|
||||
|
||||
Insertar datos:
|
||||
|
||||
``` sql
|
||||
INSERT INTO stripe_log_table VALUES (now(),'REGULAR','The first regular message')
|
||||
INSERT INTO stripe_log_table VALUES (now(),'REGULAR','The second regular message'),(now(),'WARNING','The first warning message')
|
||||
```
|
||||
|
||||
Se utilizaron dos `INSERT` consultas para crear dos bloques de datos dentro del `data.bin` file.
|
||||
|
||||
ClickHouse usa múltiples subprocesos al seleccionar datos. Cada subproceso lee un bloque de datos separado y devuelve las filas resultantes de forma independiente a medida que termina. Como resultado, el orden de los bloques de filas en la salida no coincide con el orden de los mismos bloques en la entrada en la mayoría de los casos. Por ejemplo:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM stripe_log_table
|
||||
```
|
||||
|
||||
``` text
|
||||
┌───────────timestamp─┬─message_type─┬─message────────────────────┐
|
||||
│ 2019-01-18 14:27:32 │ REGULAR │ The second regular message │
|
||||
│ 2019-01-18 14:34:53 │ WARNING │ The first warning message │
|
||||
└─────────────────────┴──────────────┴────────────────────────────┘
|
||||
┌───────────timestamp─┬─message_type─┬─message───────────────────┐
|
||||
│ 2019-01-18 14:23:43 │ REGULAR │ The first regular message │
|
||||
└─────────────────────┴──────────────┴───────────────────────────┘
|
||||
```
|
||||
|
||||
Ordenación de los resultados (orden ascendente por defecto):
|
||||
|
||||
``` sql
|
||||
SELECT * FROM stripe_log_table ORDER BY timestamp
|
||||
```
|
||||
|
||||
``` text
|
||||
┌───────────timestamp─┬─message_type─┬─message────────────────────┐
|
||||
│ 2019-01-18 14:23:43 │ REGULAR │ The first regular message │
|
||||
│ 2019-01-18 14:27:32 │ REGULAR │ The second regular message │
|
||||
│ 2019-01-18 14:34:53 │ WARNING │ The first warning message │
|
||||
└─────────────────────┴──────────────┴────────────────────────────┘
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/stripelog/) <!--hide-->
|
@ -1,16 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 34
|
||||
toc_title: TinyLog
|
||||
---
|
||||
|
||||
# TinyLog {#tinylog}
|
||||
|
||||
El motor pertenece a la familia de motores de registro. Ver [Familia del motor de registro](index.md) para las propiedades comunes de los motores de registro y sus diferencias.
|
||||
|
||||
Este motor de tablas se usa normalmente con el método write-once: escribir datos una vez, luego leerlos tantas veces como sea necesario. Por ejemplo, puede usar `TinyLog`-type tablas para datos intermedios que se procesan en pequeños lotes. Tenga en cuenta que el almacenamiento de datos en un gran número de tablas pequeñas es ineficiente.
|
||||
|
||||
Las consultas se ejecutan en una sola secuencia. En otras palabras, este motor está diseñado para tablas relativamente pequeñas (hasta aproximadamente 1,000,000 filas). Tiene sentido usar este motor de tablas si tiene muchas tablas pequeñas, ya que es más simple que el [Registro](log.md) motor (menos archivos necesitan ser abiertos).
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/tinylog/) <!--hide-->
|
@ -1,105 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 35
|
||||
toc_title: "Agregaci\xF3nMergeTree"
|
||||
---
|
||||
|
||||
# Aggregatingmergetree {#aggregatingmergetree}
|
||||
|
||||
El motor hereda de [Método de codificación de datos:](mergetree.md#table_engines-mergetree), alterando la lógica para la fusión de partes de datos. ClickHouse reemplaza todas las filas con la misma clave principal (o más exactamente, con la misma [clave de clasificación](mergetree.md)) con una sola fila (dentro de una parte de datos) que almacena una combinación de estados de funciones agregadas.
|
||||
|
||||
Usted puede utilizar `AggregatingMergeTree` tablas para la agregación de datos incrementales, incluidas las vistas materializadas agregadas.
|
||||
|
||||
El motor procesa todas las columnas con los siguientes tipos:
|
||||
|
||||
- [AggregateFunction](../../../sql-reference/data-types/aggregatefunction.md)
|
||||
- [SimpleAggregateFunction](../../../sql-reference/data-types/simpleaggregatefunction.md)
|
||||
|
||||
Es apropiado usar `AggregatingMergeTree` si reduce el número de filas por pedidos.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = AggregatingMergeTree()
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[SAMPLE BY expr]
|
||||
[TTL expr]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Para obtener una descripción de los parámetros de solicitud, consulte [descripción de la solicitud](../../../sql-reference/statements/create.md).
|
||||
|
||||
**Cláusulas de consulta**
|
||||
|
||||
Al crear un `AggregatingMergeTree` mesa de la misma [clausula](mergetree.md) se requieren, como al crear un `MergeTree` tabla.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No use este método en proyectos nuevos y, si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE [=] AggregatingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity)
|
||||
```
|
||||
|
||||
Todos los parámetros tienen el mismo significado que en `MergeTree`.
|
||||
</details>
|
||||
|
||||
## SELECCIONAR e INSERTAR {#select-and-insert}
|
||||
|
||||
Para insertar datos, utilice [INSERT SELECT](../../../sql-reference/statements/insert-into.md) consulta con funciones agregadas -State-.
|
||||
Al seleccionar datos de `AggregatingMergeTree` mesa, uso `GROUP BY` cláusula y las mismas funciones agregadas que al insertar datos, pero usando `-Merge` sufijo.
|
||||
|
||||
En los resultados de `SELECT` consulta, los valores de `AggregateFunction` tipo tiene representación binaria específica de la implementación para todos los formatos de salida de ClickHouse. Si volcar datos en, por ejemplo, `TabSeparated` formato con `SELECT` consulta entonces este volcado se puede cargar de nuevo usando `INSERT` consulta.
|
||||
|
||||
## Ejemplo de una vista materializada agregada {#example-of-an-aggregated-materialized-view}
|
||||
|
||||
`AggregatingMergeTree` vista materializada que mira el `test.visits` tabla:
|
||||
|
||||
``` sql
|
||||
CREATE MATERIALIZED VIEW test.basic
|
||||
ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate)
|
||||
AS SELECT
|
||||
CounterID,
|
||||
StartDate,
|
||||
sumState(Sign) AS Visits,
|
||||
uniqState(UserID) AS Users
|
||||
FROM test.visits
|
||||
GROUP BY CounterID, StartDate;
|
||||
```
|
||||
|
||||
Insertar datos en el `test.visits` tabla.
|
||||
|
||||
``` sql
|
||||
INSERT INTO test.visits ...
|
||||
```
|
||||
|
||||
Los datos se insertan tanto en la tabla como en la vista `test.basic` que realizará la agregación.
|
||||
|
||||
Para obtener los datos agregados, necesitamos ejecutar una consulta como `SELECT ... GROUP BY ...` de la vista `test.basic`:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
StartDate,
|
||||
sumMerge(Visits) AS Visits,
|
||||
uniqMerge(Users) AS Users
|
||||
FROM test.basic
|
||||
GROUP BY StartDate
|
||||
ORDER BY StartDate;
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/aggregatingmergetree/) <!--hide-->
|
@ -1,306 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 36
|
||||
toc_title: ColapsarMergeTree
|
||||
---
|
||||
|
||||
# ColapsarMergeTree {#table_engine-collapsingmergetree}
|
||||
|
||||
El motor hereda de [Método de codificación de datos:](mergetree.md) y agrega la lógica de las filas que colapsan al algoritmo de fusión de partes de datos.
|
||||
|
||||
`CollapsingMergeTree` elimina de forma asincrónica (colapsa) pares de filas si todos los campos de una clave de ordenación (`ORDER BY`) son equivalentes excepto el campo particular `Sign` que puede tener `1` y `-1` valor. Las filas sin un par se mantienen. Para más detalles, consulte el [Derrumbar](#table_engine-collapsingmergetree-collapsing) sección del documento.
|
||||
|
||||
El motor puede reducir significativamente el volumen de almacenamiento y aumentar la eficiencia de `SELECT` consulta como consecuencia.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = CollapsingMergeTree(sign)
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[SAMPLE BY expr]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Para obtener una descripción de los parámetros de consulta, consulte [descripción de la consulta](../../../sql-reference/statements/create.md).
|
||||
|
||||
**CollapsingMergeTree Parámetros**
|
||||
|
||||
- `sign` — Name of the column with the type of row: `1` es una “state” fila, `-1` es una “cancel” fila.
|
||||
|
||||
Column data type — `Int8`.
|
||||
|
||||
**Cláusulas de consulta**
|
||||
|
||||
Al crear un `CollapsingMergeTree` mesa, la misma [cláusulas de consulta](mergetree.md#table_engine-mergetree-creating-a-table) se requieren, como al crear un `MergeTree` tabla.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No use este método en proyectos nuevos y, si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE [=] CollapsingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, sign)
|
||||
```
|
||||
|
||||
Todos los parámetros excepto `sign` el mismo significado que en `MergeTree`.
|
||||
|
||||
- `sign` — Name of the column with the type of row: `1` — “state” fila, `-1` — “cancel” fila.
|
||||
|
||||
Column Data Type — `Int8`.
|
||||
|
||||
</details>
|
||||
|
||||
## Derrumbar {#table_engine-collapsingmergetree-collapsing}
|
||||
|
||||
### Datos {#data}
|
||||
|
||||
Considere la situación en la que necesita guardar datos que cambian continuamente para algún objeto. Parece lógico tener una fila para un objeto y actualizarla en cualquier cambio, pero la operación de actualización es costosa y lenta para DBMS porque requiere la reescritura de los datos en el almacenamiento. Si necesita escribir datos rápidamente, la actualización no es aceptable, pero puede escribir los cambios de un objeto secuencialmente de la siguiente manera.
|
||||
|
||||
Utilice la columna en particular `Sign`. Si `Sign = 1` significa que la fila es un estado de un objeto, llamémoslo “state” fila. Si `Sign = -1` significa la cancelación del estado de un objeto con los mismos atributos, llamémoslo “cancel” fila.
|
||||
|
||||
Por ejemplo, queremos calcular cuántas páginas revisaron los usuarios en algún sitio y cuánto tiempo estuvieron allí. En algún momento escribimos la siguiente fila con el estado de la actividad del usuario:
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
En algún momento después registramos el cambio de actividad del usuario y lo escribimos con las siguientes dos filas.
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
La primera fila cancela el estado anterior del objeto (usuario). Debe copiar los campos clave de ordenación del estado cancelado exceptuando `Sign`.
|
||||
|
||||
La segunda fila contiene el estado actual.
|
||||
|
||||
Como solo necesitamos el último estado de actividad del usuario, las filas
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
se puede eliminar colapsando el estado no válido (antiguo) de un objeto. `CollapsingMergeTree` hace esto mientras se fusionan las partes de datos.
|
||||
|
||||
Por qué necesitamos 2 filas para cada cambio leído en el [Algoritmo](#table_engine-collapsingmergetree-collapsing-algorithm) apartado.
|
||||
|
||||
**Propiedades peculiares de tal enfoque**
|
||||
|
||||
1. El programa que escribe los datos debe recordar el estado de un objeto para poder cancelarlo. “Cancel” debe contener copias de los campos de clave de ordenación “state” y lo opuesto `Sign`. Aumenta el tamaño inicial de almacenamiento, pero permite escribir los datos rápidamente.
|
||||
2. Las matrices de largo crecimiento en columnas reducen la eficiencia del motor debido a la carga para escribir. Los datos más sencillos, mayor será la eficiencia.
|
||||
3. El `SELECT` Los resultados dependen en gran medida de la consistencia del historial de cambios de objetos. Sea preciso al preparar los datos para insertarlos. Puede obtener resultados impredecibles en datos incoherentes, por ejemplo, valores negativos para métricas no negativas, como la profundidad de la sesión.
|
||||
|
||||
### Algoritmo {#table_engine-collapsingmergetree-collapsing-algorithm}
|
||||
|
||||
Cuando ClickHouse combina partes de datos, cada grupo de filas consecutivas tiene la misma clave de ordenación (`ORDER BY`) se reduce a no más de dos filas, una con `Sign = 1` (“state” fila) y otro con `Sign = -1` (“cancel” fila). En otras palabras, las entradas colapsan.
|
||||
|
||||
Para cada parte de datos resultante, ClickHouse guarda:
|
||||
|
||||
1. El primero “cancel” y el último “state” si el número de “state” y “cancel” y la última fila es una “state” fila.
|
||||
2. El último “state” fila, si hay más “state” filas que “cancel” filas.
|
||||
3. El primero “cancel” fila, si hay más “cancel” filas que “state” filas.
|
||||
4. Ninguna de las filas, en todos los demás casos.
|
||||
|
||||
También cuando hay al menos 2 más “state” filas que “cancel” filas, o al menos 2 más “cancel” filas entonces “state” fila, la fusión continúa, pero ClickHouse trata esta situación como un error lógico y la registra en el registro del servidor. Este error puede producirse si se insertan los mismos datos más de una vez.
|
||||
|
||||
Por lo tanto, el colapso no debe cambiar los resultados del cálculo de las estadísticas.
|
||||
Los cambios colapsaron gradualmente para que al final solo quedara el último estado de casi todos los objetos.
|
||||
|
||||
El `Sign` se requiere porque el algoritmo de fusión no garantiza que todas las filas con la misma clave de clasificación estén en la misma parte de datos resultante e incluso en el mismo servidor físico. Proceso de ClickHouse `SELECT` consultas con múltiples hilos, y no puede predecir el orden de las filas en el resultado. La agregación es necesaria si hay una necesidad de obtener completamente “collapsed” datos de `CollapsingMergeTree` tabla.
|
||||
|
||||
Para finalizar el colapso, escriba una consulta con `GROUP BY` cláusula y funciones agregadas que representan el signo. Por ejemplo, para calcular la cantidad, use `sum(Sign)` en lugar de `count()`. Para calcular la suma de algo, use `sum(Sign * x)` en lugar de `sum(x)` y así sucesivamente, y también añadir `HAVING sum(Sign) > 0`.
|
||||
|
||||
Los agregados `count`, `sum` y `avg` podría calcularse de esta manera. El agregado `uniq` podría calcularse si un objeto tiene al menos un estado no colapsado. Los agregados `min` y `max` no se pudo calcular porque `CollapsingMergeTree` no guarda el historial de valores de los estados colapsados.
|
||||
|
||||
Si necesita extraer datos sin agregación (por ejemplo, para comprobar si hay filas presentes cuyos valores más recientes coinciden con ciertas condiciones), puede utilizar el `FINAL` modificador para el `FROM` clausula. Este enfoque es significativamente menos eficiente.
|
||||
|
||||
## Ejemplo de uso {#example-of-use}
|
||||
|
||||
Datos de ejemplo:
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
Creación de la tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE UAct
|
||||
(
|
||||
UserID UInt64,
|
||||
PageViews UInt8,
|
||||
Duration UInt8,
|
||||
Sign Int8
|
||||
)
|
||||
ENGINE = CollapsingMergeTree(Sign)
|
||||
ORDER BY UserID
|
||||
```
|
||||
|
||||
Inserción de los datos:
|
||||
|
||||
``` sql
|
||||
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, 1)
|
||||
```
|
||||
|
||||
``` sql
|
||||
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, -1),(4324182021466249494, 6, 185, 1)
|
||||
```
|
||||
|
||||
Usamos dos `INSERT` consultas para crear dos partes de datos diferentes. Si insertamos los datos con una consulta, ClickHouse crea una parte de datos y nunca realizará ninguna fusión.
|
||||
|
||||
Obtener los datos:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM UAct
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
¿Qué vemos y dónde está colapsando?
|
||||
|
||||
Con dos `INSERT` consultas, hemos creado 2 partes de datos. El `SELECT` la consulta se realizó en 2 hilos, y obtuvimos un orden aleatorio de filas. No se ha producido un colapso porque todavía no se había fusionado las partes de datos. ClickHouse fusiona parte de datos en un momento desconocido que no podemos predecir.
|
||||
|
||||
Por lo tanto, necesitamos agregación:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
UserID,
|
||||
sum(PageViews * Sign) AS PageViews,
|
||||
sum(Duration * Sign) AS Duration
|
||||
FROM UAct
|
||||
GROUP BY UserID
|
||||
HAVING sum(Sign) > 0
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │
|
||||
└─────────────────────┴───────────┴──────────┘
|
||||
```
|
||||
|
||||
Si no necesitamos agregación y queremos forzar el colapso, podemos usar `FINAL` modificador para `FROM` clausula.
|
||||
|
||||
``` sql
|
||||
SELECT * FROM UAct FINAL
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
Esta forma de seleccionar los datos es muy ineficiente. No lo use para mesas grandes.
|
||||
|
||||
## Ejemplo de otro enfoque {#example-of-another-approach}
|
||||
|
||||
Datos de ejemplo:
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │
|
||||
│ 4324182021466249494 │ -5 │ -146 │ -1 │
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
La idea es que las fusiones tengan en cuenta solo los campos clave. Y en el “Cancel” línea podemos especificar valores negativos que igualan la versión anterior de la fila al sumar sin usar la columna Sign. Para este enfoque, es necesario cambiar el tipo de datos `PageViews`,`Duration` para almacenar valores negativos de UInt8 -\> Int16.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE UAct
|
||||
(
|
||||
UserID UInt64,
|
||||
PageViews Int16,
|
||||
Duration Int16,
|
||||
Sign Int8
|
||||
)
|
||||
ENGINE = CollapsingMergeTree(Sign)
|
||||
ORDER BY UserID
|
||||
```
|
||||
|
||||
Vamos a probar el enfoque:
|
||||
|
||||
``` sql
|
||||
insert into UAct values(4324182021466249494, 5, 146, 1);
|
||||
insert into UAct values(4324182021466249494, -5, -146, -1);
|
||||
insert into UAct values(4324182021466249494, 6, 185, 1);
|
||||
|
||||
select * from UAct final; // avoid using final in production (just for a test or small tables)
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
UserID,
|
||||
sum(PageViews) AS PageViews,
|
||||
sum(Duration) AS Duration
|
||||
FROM UAct
|
||||
GROUP BY UserID
|
||||
```text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │
|
||||
└─────────────────────┴───────────┴──────────┘
|
||||
```
|
||||
|
||||
``` sqk
|
||||
select count() FROM UAct
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─count()─┐
|
||||
│ 3 │
|
||||
└─────────┘
|
||||
```
|
||||
|
||||
``` sql
|
||||
optimize table UAct final;
|
||||
|
||||
select * FROM UAct
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┘
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/collapsingmergetree/) <!--hide-->
|
@ -1,127 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 32
|
||||
toc_title: "Clave de partici\xF3n personalizada"
|
||||
---
|
||||
|
||||
# Clave de partición personalizada {#custom-partitioning-key}
|
||||
|
||||
La partición está disponible para el [Método de codificación de datos:](mergetree.md) mesas familiares (incluyendo [repetición](replication.md) tabla). [Vistas materializadas](../special/materializedview.md#materializedview) basado en tablas MergeTree soporte de particionamiento, también.
|
||||
|
||||
Una partición es una combinación lógica de registros en una tabla por un criterio especificado. Puede establecer una partición por un criterio arbitrario, como por mes, por día o por tipo de evento. Cada partición se almacena por separado para simplificar las manipulaciones de estos datos. Al acceder a los datos, ClickHouse utiliza el subconjunto más pequeño de particiones posible.
|
||||
|
||||
La partición se especifica en el `PARTITION BY expr` cláusula cuando [creando una tabla](mergetree.md#table_engine-mergetree-creating-a-table). La clave de partición puede ser cualquier expresión de las columnas de la tabla. Por ejemplo, para especificar la partición por mes, utilice la expresión `toYYYYMM(date_column)`:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE visits
|
||||
(
|
||||
VisitDate Date,
|
||||
Hour UInt8,
|
||||
ClientID UUID
|
||||
)
|
||||
ENGINE = MergeTree()
|
||||
PARTITION BY toYYYYMM(VisitDate)
|
||||
ORDER BY Hour;
|
||||
```
|
||||
|
||||
La clave de partición también puede ser una tupla de expresiones (similar a la [clave primaria](mergetree.md#primary-keys-and-indexes-in-queries)). Por ejemplo:
|
||||
|
||||
``` sql
|
||||
ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
|
||||
PARTITION BY (toMonday(StartDate), EventType)
|
||||
ORDER BY (CounterID, StartDate, intHash32(UserID));
|
||||
```
|
||||
|
||||
En este ejemplo, establecemos la partición por los tipos de eventos que se produjeron durante la semana actual.
|
||||
|
||||
Al insertar datos nuevos en una tabla, estos datos se almacenan como una parte separada (porción) ordenada por la clave principal. En 10-15 minutos después de insertar, las partes de la misma partición se fusionan en toda la parte.
|
||||
|
||||
!!! info "INFO"
|
||||
Una combinación solo funciona para partes de datos que tienen el mismo valor para la expresión de partición. Esto significa **no deberías hacer particiones demasiado granulares** (más de un millar de particiones). De lo contrario, el `SELECT` consulta funciona mal debido a un número excesivamente grande de archivos en el sistema de archivos y descriptores de archivos abiertos.
|
||||
|
||||
Utilice el [sistema.parte](../../../operations/system-tables.md#system_tables-parts) tabla para ver las partes y particiones de la tabla. Por ejemplo, supongamos que tenemos un `visits` tabla con partición por mes. Vamos a realizar el `SELECT` consulta para el `system.parts` tabla:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
partition,
|
||||
name,
|
||||
active
|
||||
FROM system.parts
|
||||
WHERE table = 'visits'
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─partition─┬─name───────────┬─active─┐
|
||||
│ 201901 │ 201901_1_3_1 │ 0 │
|
||||
│ 201901 │ 201901_1_9_2 │ 1 │
|
||||
│ 201901 │ 201901_8_8_0 │ 0 │
|
||||
│ 201901 │ 201901_9_9_0 │ 0 │
|
||||
│ 201902 │ 201902_4_6_1 │ 1 │
|
||||
│ 201902 │ 201902_10_10_0 │ 1 │
|
||||
│ 201902 │ 201902_11_11_0 │ 1 │
|
||||
└───────────┴────────────────┴────────┘
|
||||
```
|
||||
|
||||
El `partition` columna contiene los nombres de las particiones. Hay dos particiones en este ejemplo: `201901` y `201902`. Puede utilizar este valor de columna para especificar el nombre de partición en [ALTER … PARTITION](#alter_manipulations-with-partitions) consulta.
|
||||
|
||||
El `name` columna contiene los nombres de las partes de datos de partición. Puede utilizar esta columna para especificar el nombre de la pieza [ALTER ATTACH PART](#alter_attach-partition) consulta.
|
||||
|
||||
Vamos a desglosar el nombre de la primera parte: `201901_1_3_1`:
|
||||
|
||||
- `201901` es el nombre de la partición.
|
||||
- `1` es el número mínimo del bloque de datos.
|
||||
- `3` es el número máximo del bloque de datos.
|
||||
- `1` es el nivel de fragmento (la profundidad del árbol de fusión del que se forma).
|
||||
|
||||
!!! info "INFO"
|
||||
Las partes de las tablas de tipo antiguo tienen el nombre: `20190117_20190123_2_2_0` (fecha mínima - fecha máxima - número de bloque mínimo - número de bloque máximo - nivel).
|
||||
|
||||
El `active` columna muestra el estado de la pieza. `1` está activo; `0` está inactivo. Las partes inactivas son, por ejemplo, las partes de origen que quedan después de fusionarse con una parte más grande. Las partes de datos dañadas también se indican como inactivas.
|
||||
|
||||
Como puede ver en el ejemplo, hay varias partes separadas de la misma partición (por ejemplo, `201901_1_3_1` y `201901_1_9_2`). Esto significa que estas partes aún no están fusionadas. ClickHouse combina las partes insertadas de datos periódicamente, aproximadamente 15 minutos después de la inserción. Además, puede realizar una fusión no programada utilizando el [OPTIMIZE](../../../sql-reference/statements/misc.md#misc_operations-optimize) consulta. Ejemplo:
|
||||
|
||||
``` sql
|
||||
OPTIMIZE TABLE visits PARTITION 201902;
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─partition─┬─name───────────┬─active─┐
|
||||
│ 201901 │ 201901_1_3_1 │ 0 │
|
||||
│ 201901 │ 201901_1_9_2 │ 1 │
|
||||
│ 201901 │ 201901_8_8_0 │ 0 │
|
||||
│ 201901 │ 201901_9_9_0 │ 0 │
|
||||
│ 201902 │ 201902_4_6_1 │ 0 │
|
||||
│ 201902 │ 201902_4_11_2 │ 1 │
|
||||
│ 201902 │ 201902_10_10_0 │ 0 │
|
||||
│ 201902 │ 201902_11_11_0 │ 0 │
|
||||
└───────────┴────────────────┴────────┘
|
||||
```
|
||||
|
||||
Las partes inactivas se eliminarán aproximadamente 10 minutos después de la fusión.
|
||||
|
||||
Otra forma de ver un conjunto de partes y particiones es ir al directorio de la tabla: `/var/lib/clickhouse/data/<database>/<table>/`. Por ejemplo:
|
||||
|
||||
``` bash
|
||||
/var/lib/clickhouse/data/default/visits$ ls -l
|
||||
total 40
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 201901_1_3_1
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201901_1_9_2
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 15:52 201901_8_8_0
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 15:52 201901_9_9_0
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201902_10_10_0
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:17 201902_11_11_0
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 16:19 201902_4_11_2
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 5 12:09 201902_4_6_1
|
||||
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 detached
|
||||
```
|
||||
|
||||
Carpeta ‘201901_1_1_0’, ‘201901_1_7_1’ y así sucesivamente son los directorios de las partes. Cada parte se relaciona con una partición correspondiente y contiene datos solo para un mes determinado (la tabla de este ejemplo tiene particiones por mes).
|
||||
|
||||
El `detached` el directorio contiene partes que se separaron de la tabla utilizando el [DETACH](../../../sql-reference/statements/alter.md#alter_detach-partition) consulta. Las partes dañadas también se mueven a este directorio, en lugar de eliminarse. El servidor no utiliza las piezas del `detached` directory. You can add, delete, or modify the data in this directory at any time – the server will not know about this until you run the [ATTACH](../../../sql-reference/statements/alter.md#alter_attach-partition) consulta.
|
||||
|
||||
Tenga en cuenta que en el servidor operativo, no puede cambiar manualmente el conjunto de piezas o sus datos en el sistema de archivos, ya que el servidor no lo sabrá. Para tablas no replicadas, puede hacer esto cuando se detiene el servidor, pero no se recomienda. Para tablas replicadas, el conjunto de piezas no se puede cambiar en ningún caso.
|
||||
|
||||
ClickHouse le permite realizar operaciones con las particiones: eliminarlas, copiar de una tabla a otra o crear una copia de seguridad. Consulte la lista de todas las operaciones en la sección [Manipulaciones con particiones y piezas](../../../sql-reference/statements/alter.md#alter_manipulations-with-partitions).
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/custom_partitioning_key/) <!--hide-->
|
@ -1,174 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 38
|
||||
toc_title: GraphiteMergeTree
|
||||
---
|
||||
|
||||
# GraphiteMergeTree {#graphitemergetree}
|
||||
|
||||
Este motor está diseñado para el adelgazamiento y la agregación / promedio (rollup) [Grafito](http://graphite.readthedocs.io/en/latest/index.html) datos. Puede ser útil para los desarrolladores que desean usar ClickHouse como almacén de datos para Graphite.
|
||||
|
||||
Puede usar cualquier motor de tabla ClickHouse para almacenar los datos de Graphite si no necesita un paquete acumulativo, pero si necesita un paquete acumulativo, use `GraphiteMergeTree`. El motor reduce el volumen de almacenamiento y aumenta la eficiencia de las consultas de Graphite.
|
||||
|
||||
El motor hereda propiedades de [Método de codificación de datos:](mergetree.md).
|
||||
|
||||
## Creación de una tabla {#creating-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
Path String,
|
||||
Time DateTime,
|
||||
Value <Numeric_type>,
|
||||
Version <Numeric_type>
|
||||
...
|
||||
) ENGINE = GraphiteMergeTree(config_section)
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[SAMPLE BY expr]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Vea una descripción detallada del [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) consulta.
|
||||
|
||||
Una tabla para los datos de grafito debe tener las siguientes columnas para los siguientes datos:
|
||||
|
||||
- Nombre métrico (sensor de grafito). Tipo de datos: `String`.
|
||||
|
||||
- Tiempo de medición de la métrica. Tipo de datos: `DateTime`.
|
||||
|
||||
- Valor de la métrica. Tipo de datos: cualquier numérico.
|
||||
|
||||
- Versión de la métrica. Tipo de datos: cualquier numérico.
|
||||
|
||||
ClickHouse guarda las filas con la versión más alta o la última escrita si las versiones son las mismas. Otras filas se eliminan durante la fusión de partes de datos.
|
||||
|
||||
Los nombres de estas columnas deben establecerse en la configuración acumulativa.
|
||||
|
||||
**GraphiteMergeTree parámetros**
|
||||
|
||||
- `config_section` — Name of the section in the configuration file, where are the rules of rollup set.
|
||||
|
||||
**Cláusulas de consulta**
|
||||
|
||||
Al crear un `GraphiteMergeTree` mesa, la misma [clausula](mergetree.md#table_engine-mergetree-creating-a-table) se requieren, como al crear un `MergeTree` tabla.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No use este método en proyectos nuevos y, si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
EventDate Date,
|
||||
Path String,
|
||||
Time DateTime,
|
||||
Value <Numeric_type>,
|
||||
Version <Numeric_type>
|
||||
...
|
||||
) ENGINE [=] GraphiteMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, config_section)
|
||||
```
|
||||
|
||||
Todos los parámetros excepto `config_section` el mismo significado que en `MergeTree`.
|
||||
|
||||
- `config_section` — Name of the section in the configuration file, where are the rules of rollup set.
|
||||
|
||||
</details>
|
||||
|
||||
## Configuración acumulativa {#rollup-configuration}
|
||||
|
||||
La configuración del paquete acumulativo está definida por [graphite_rollup](../../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-graphite) parámetro en la configuración del servidor. El nombre del parámetro podría ser cualquiera. Puede crear varias configuraciones y usarlas para diferentes tablas.
|
||||
|
||||
Estructura de configuración Rollup:
|
||||
|
||||
required-columns
|
||||
patterns
|
||||
|
||||
### Columnas requeridas {#required-columns}
|
||||
|
||||
- `path_column_name` — The name of the column storing the metric name (Graphite sensor). Default value: `Path`.
|
||||
- `time_column_name` — The name of the column storing the time of measuring the metric. Default value: `Time`.
|
||||
- `value_column_name` — The name of the column storing the value of the metric at the time set in `time_column_name`. Valor predeterminado: `Value`.
|
||||
- `version_column_name` — The name of the column storing the version of the metric. Default value: `Timestamp`.
|
||||
|
||||
### Patrón {#patterns}
|
||||
|
||||
Estructura del `patterns` apartado:
|
||||
|
||||
``` text
|
||||
pattern
|
||||
regexp
|
||||
function
|
||||
pattern
|
||||
regexp
|
||||
age + precision
|
||||
...
|
||||
pattern
|
||||
regexp
|
||||
function
|
||||
age + precision
|
||||
...
|
||||
pattern
|
||||
...
|
||||
default
|
||||
function
|
||||
age + precision
|
||||
...
|
||||
```
|
||||
|
||||
!!! warning "Atención"
|
||||
Los patrones deben ser estrictamente ordenados:
|
||||
|
||||
1. Patterns without `function` or `retention`.
|
||||
1. Patterns with both `function` and `retention`.
|
||||
1. Pattern `default`.
|
||||
|
||||
Al procesar una fila, ClickHouse comprueba las reglas en el `pattern` apartado. Cada uno de `pattern` (incluir `default` secciones pueden contener `function` parámetro para la agregación, `retention` parámetros o ambos. Si el nombre de la métrica coincide con `regexp`, las reglas de la `pattern` sección (o secciones); de lo contrario, las reglas de la `default` sección se utilizan.
|
||||
|
||||
Campos para `pattern` y `default` apartado:
|
||||
|
||||
- `regexp`– A pattern for the metric name.
|
||||
- `age` – The minimum age of the data in seconds.
|
||||
- `precision`– How precisely to define the age of the data in seconds. Should be a divisor for 86400 (seconds in a day).
|
||||
- `function` – The name of the aggregating function to apply to data whose age falls within the range `[age, age + precision]`.
|
||||
|
||||
### Ejemplo de configuración {#configuration-example}
|
||||
|
||||
``` xml
|
||||
<graphite_rollup>
|
||||
<version_column_name>Version</version_column_name>
|
||||
<pattern>
|
||||
<regexp>click_cost</regexp>
|
||||
<function>any</function>
|
||||
<retention>
|
||||
<age>0</age>
|
||||
<precision>5</precision>
|
||||
</retention>
|
||||
<retention>
|
||||
<age>86400</age>
|
||||
<precision>60</precision>
|
||||
</retention>
|
||||
</pattern>
|
||||
<default>
|
||||
<function>max</function>
|
||||
<retention>
|
||||
<age>0</age>
|
||||
<precision>60</precision>
|
||||
</retention>
|
||||
<retention>
|
||||
<age>3600</age>
|
||||
<precision>300</precision>
|
||||
</retention>
|
||||
<retention>
|
||||
<age>86400</age>
|
||||
<precision>3600</precision>
|
||||
</retention>
|
||||
</default>
|
||||
</graphite_rollup>
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/graphitemergetree/) <!--hide-->
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Familia MergeTree
|
||||
toc_priority: 28
|
||||
---
|
||||
|
||||
|
@ -1,654 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 30
|
||||
toc_title: "M\xE9todo de codificaci\xF3n de datos:"
|
||||
---
|
||||
|
||||
# Método de codificación de datos: {#table_engines-mergetree}
|
||||
|
||||
El `MergeTree` motor y otros motores de esta familia (`*MergeTree`) son los motores de mesa ClickHouse más robustos.
|
||||
|
||||
Motores en el `MergeTree` familia están diseñados para insertar una gran cantidad de datos en una tabla. Los datos se escriben rápidamente en la tabla parte por parte, luego se aplican reglas para fusionar las partes en segundo plano. Este método es mucho más eficiente que reescribir continuamente los datos en almacenamiento durante la inserción.
|
||||
|
||||
Principales características:
|
||||
|
||||
- Almacena datos ordenados por clave principal.
|
||||
|
||||
Esto le permite crear un pequeño índice disperso que ayuda a encontrar datos más rápido.
|
||||
|
||||
- Las particiones se pueden utilizar si [clave de partición](custom-partitioning-key.md) se especifica.
|
||||
|
||||
ClickHouse admite ciertas operaciones con particiones que son más efectivas que las operaciones generales en los mismos datos con el mismo resultado. ClickHouse también corta automáticamente los datos de partición donde se especifica la clave de partición en la consulta. Esto también mejora el rendimiento de las consultas.
|
||||
|
||||
- Soporte de replicación de datos.
|
||||
|
||||
La familia de `ReplicatedMergeTree` proporciona la replicación de datos. Para obtener más información, consulte [Replicación de datos](replication.md).
|
||||
|
||||
- Soporte de muestreo de datos.
|
||||
|
||||
Si es necesario, puede establecer el método de muestreo de datos en la tabla.
|
||||
|
||||
!!! info "INFO"
|
||||
El [Fusionar](../special/merge.md#merge) el motor no pertenece al `*MergeTree` familia.
|
||||
|
||||
## Creación de una tabla {#table_engine-mergetree-creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
|
||||
...
|
||||
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
|
||||
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
|
||||
) ENGINE = MergeTree()
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[PRIMARY KEY expr]
|
||||
[SAMPLE BY expr]
|
||||
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Para obtener una descripción de los parámetros, consulte [Descripción de la consulta CREATE](../../../sql-reference/statements/create.md).
|
||||
|
||||
!!! note "Nota"
|
||||
`INDEX` es una característica experimental, ver [Índices de saltos de datos](#table_engine-mergetree-data_skipping-indexes).
|
||||
|
||||
### Cláusulas de consulta {#mergetree-query-clauses}
|
||||
|
||||
- `ENGINE` — Name and parameters of the engine. `ENGINE = MergeTree()`. El `MergeTree` el motor no tiene parámetros.
|
||||
|
||||
- `PARTITION BY` — The [clave de partición](custom-partitioning-key.md).
|
||||
|
||||
Para particionar por mes, utilice el `toYYYYMM(date_column)` expresión, donde `date_column` es una columna con una fecha del tipo [Fecha](../../../sql-reference/data-types/date.md). Los nombres de partición aquí tienen el `"YYYYMM"` formato.
|
||||
|
||||
- `ORDER BY` — The sorting key.
|
||||
|
||||
Una tupla de columnas o expresiones arbitrarias. Ejemplo: `ORDER BY (CounterID, EventDate)`.
|
||||
|
||||
- `PRIMARY KEY` — The primary key if it [difiere de la clave de clasificación](#choosing-a-primary-key-that-differs-from-the-sorting-key).
|
||||
|
||||
De forma predeterminada, la clave principal es la misma que la clave de ordenación (que se especifica `ORDER BY` clausula). Por lo tanto, en la mayoría de los casos no es necesario especificar un `PRIMARY KEY` clausula.
|
||||
|
||||
- `SAMPLE BY` — An expression for sampling.
|
||||
|
||||
Si se utiliza una expresión de muestreo, la clave principal debe contenerla. Ejemplo: `SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID))`.
|
||||
|
||||
- `TTL` — A list of rules specifying storage duration of rows and defining logic of automatic parts movement [entre discos y volúmenes](#table_engine-mergetree-multiple-volumes).
|
||||
|
||||
La expresión debe tener una `Date` o `DateTime` columna como resultado. Ejemplo:
|
||||
`TTL date + INTERVAL 1 DAY`
|
||||
|
||||
Tipo de regla `DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'` especifica una acción que debe realizarse con la pieza si la expresión está satisfecha (alcanza la hora actual): eliminación de filas caducadas, mover una pieza (si la expresión está satisfecha para todas las filas de una pieza) al disco especificado (`TO DISK 'xxx'`) o al volumen (`TO VOLUME 'xxx'`). El tipo predeterminado de la regla es la eliminación (`DELETE`). Se puede especificar una lista de varias reglas, pero no debe haber más de una `DELETE` regla.
|
||||
|
||||
Para obtener más información, consulte [TTL para columnas y tablas](#table_engine-mergetree-ttl)
|
||||
|
||||
- `SETTINGS` — Additional parameters that control the behavior of the `MergeTree`:
|
||||
|
||||
- `index_granularity` — Maximum number of data rows between the marks of an index. Default value: 8192. See [Almacenamiento de datos](#mergetree-data-storage).
|
||||
- `index_granularity_bytes` — Maximum size of data granules in bytes. Default value: 10Mb. To restrict the granule size only by number of rows, set to 0 (not recommended). See [Almacenamiento de datos](#mergetree-data-storage).
|
||||
- `enable_mixed_granularity_parts` — Enables or disables transitioning to control the granule size with the `index_granularity_bytes` configuración. Antes de la versión 19.11, sólo existía el `index_granularity` ajuste para restringir el tamaño del gránulo. El `index_granularity_bytes` mejora el rendimiento de ClickHouse al seleccionar datos de tablas con filas grandes (decenas y cientos de megabytes). Si tiene tablas con filas grandes, puede habilitar esta configuración para que las tablas mejoren la eficiencia de `SELECT` consulta.
|
||||
- `use_minimalistic_part_header_in_zookeeper` — Storage method of the data parts headers in ZooKeeper. If `use_minimalistic_part_header_in_zookeeper=1`, entonces ZooKeeper almacena menos datos. Para obtener más información, consulte [descripción del ajuste](../../../operations/server-configuration-parameters/settings.md#server-settings-use_minimalistic_part_header_in_zookeeper) en “Server configuration parameters”.
|
||||
- `min_merge_bytes_to_use_direct_io` — The minimum data volume for merge operation that is required for using direct I/O access to the storage disk. When merging data parts, ClickHouse calculates the total storage volume of all the data to be merged. If the volume exceeds `min_merge_bytes_to_use_direct_io` bytes, ClickHouse lee y escribe los datos en el disco de almacenamiento utilizando la interfaz de E / S directa (`O_DIRECT` opcion). Si `min_merge_bytes_to_use_direct_io = 0`, entonces la E/S directa está deshabilitada. Valor predeterminado: `10 * 1024 * 1024 * 1024` byte.
|
||||
<a name="mergetree_setting-merge_with_ttl_timeout"></a>
|
||||
- `merge_with_ttl_timeout` — Minimum delay in seconds before repeating a merge with TTL. Default value: 86400 (1 day).
|
||||
- `write_final_mark` — Enables or disables writing the final index mark at the end of data part (after the last byte). Default value: 1. Don't turn it off.
|
||||
- `merge_max_block_size` — Maximum number of rows in block for merge operations. Default value: 8192.
|
||||
- `storage_policy` — Storage policy. See [Uso de varios dispositivos de bloque para el almacenamiento de datos](#table_engine-mergetree-multiple-volumes).
|
||||
|
||||
**Ejemplo de configuración de secciones**
|
||||
|
||||
``` sql
|
||||
ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192
|
||||
```
|
||||
|
||||
En el ejemplo, configuramos la partición por mes.
|
||||
|
||||
También establecemos una expresión para el muestreo como un hash por el ID de usuario. Esto le permite pseudoaleatorizar los datos en la tabla para cada `CounterID` y `EventDate`. Si define un [SAMPLE](../../../sql-reference/statements/select/sample.md#select-sample-clause) cláusula al seleccionar los datos, ClickHouse devolverá una muestra de datos pseudoaleatoria uniforme para un subconjunto de usuarios.
|
||||
|
||||
El `index_granularity` se puede omitir porque 8192 es el valor predeterminado.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No utilice este método en nuevos proyectos. Si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE [=] MergeTree(date-column [, sampling_expression], (primary, key), index_granularity)
|
||||
```
|
||||
|
||||
**Parámetros MergeTree()**
|
||||
|
||||
- `date-column` — The name of a column of the [Fecha](../../../sql-reference/data-types/date.md) tipo. ClickHouse crea automáticamente particiones por mes en función de esta columna. Los nombres de partición están en el `"YYYYMM"` formato.
|
||||
- `sampling_expression` — An expression for sampling.
|
||||
- `(primary, key)` — Primary key. Type: [Tupla()](../../../sql-reference/data-types/tuple.md)
|
||||
- `index_granularity` — The granularity of an index. The number of data rows between the “marks” de un índice. El valor 8192 es apropiado para la mayoría de las tareas.
|
||||
|
||||
**Ejemplo**
|
||||
|
||||
``` sql
|
||||
MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)
|
||||
```
|
||||
|
||||
El `MergeTree` engine se configura de la misma manera que en el ejemplo anterior para el método de configuración del motor principal.
|
||||
</details>
|
||||
|
||||
## Almacenamiento de datos {#mergetree-data-storage}
|
||||
|
||||
Una tabla consta de partes de datos ordenadas por clave principal.
|
||||
|
||||
Cuando se insertan datos en una tabla, se crean partes de datos separadas y cada una de ellas se ordena lexicográficamente por clave principal. Por ejemplo, si la clave principal es `(CounterID, Date)`, los datos en la parte se ordenan por `CounterID`, y dentro de cada `CounterID` es ordenado por `Date`.
|
||||
|
||||
Los datos que pertenecen a diferentes particiones se separan en diferentes partes. En el fondo, ClickHouse combina partes de datos para un almacenamiento más eficiente. Las piezas que pertenecen a particiones diferentes no se fusionan. El mecanismo de combinación no garantiza que todas las filas con la misma clave principal estén en la misma parte de datos.
|
||||
|
||||
Cada parte de datos se divide lógicamente en gránulos. Un gránulo es el conjunto de datos indivisibles más pequeño que ClickHouse lee al seleccionar datos. ClickHouse no divide filas o valores, por lo que cada gránulo siempre contiene un número entero de filas. La primera fila de un gránulo está marcada con el valor de la clave principal de la fila. Para cada parte de datos, ClickHouse crea un archivo de índice que almacena las marcas. Para cada columna, ya sea en la clave principal o no, ClickHouse también almacena las mismas marcas. Estas marcas le permiten encontrar datos directamente en archivos de columnas.
|
||||
|
||||
El tamaño del gránulo es restringido por `index_granularity` y `index_granularity_bytes` configuración del motor de tabla. El número de filas en un gránulo se encuentra en el `[1, index_granularity]` rango, dependiendo del tamaño de las filas. El tamaño de un gránulo puede exceder `index_granularity_bytes` si el tamaño de una sola fila es mayor que el valor de la configuración. En este caso, el tamaño del gránulo es igual al tamaño de la fila.
|
||||
|
||||
## Claves e índices principales en consultas {#primary-keys-and-indexes-in-queries}
|
||||
|
||||
Tome el `(CounterID, Date)` clave primaria como ejemplo. En este caso, la clasificación y el índice se pueden ilustrar de la siguiente manera:
|
||||
|
||||
Whole data: [---------------------------------------------]
|
||||
CounterID: [aaaaaaaaaaaaaaaaaabbbbcdeeeeeeeeeeeeefgggggggghhhhhhhhhiiiiiiiiikllllllll]
|
||||
Date: [1111111222222233331233211111222222333211111112122222223111112223311122333]
|
||||
Marks: | | | | | | | | | | |
|
||||
a,1 a,2 a,3 b,3 e,2 e,3 g,1 h,2 i,1 i,3 l,3
|
||||
Marks numbers: 0 1 2 3 4 5 6 7 8 9 10
|
||||
|
||||
Si la consulta de datos especifica:
|
||||
|
||||
- `CounterID in ('a', 'h')`, el servidor lee los datos en los rangos de marcas `[0, 3)` y `[6, 8)`.
|
||||
- `CounterID IN ('a', 'h') AND Date = 3`, el servidor lee los datos en los rangos de marcas `[1, 3)` y `[7, 8)`.
|
||||
- `Date = 3`, el servidor lee los datos en el rango de marcas `[1, 10]`.
|
||||
|
||||
Los ejemplos anteriores muestran que siempre es más efectivo usar un índice que un análisis completo.
|
||||
|
||||
Un índice disperso permite leer datos adicionales. Al leer un único rango de la clave primaria, hasta `index_granularity * 2` se pueden leer filas adicionales en cada bloque de datos.
|
||||
|
||||
Los índices dispersos le permiten trabajar con una gran cantidad de filas de tabla, porque en la mayoría de los casos, dichos índices caben en la RAM de la computadora.
|
||||
|
||||
ClickHouse no requiere una clave principal única. Puede insertar varias filas con la misma clave principal.
|
||||
|
||||
### Selección de la clave principal {#selecting-the-primary-key}
|
||||
|
||||
El número de columnas en la clave principal no está explícitamente limitado. Dependiendo de la estructura de datos, puede incluir más o menos columnas en la clave principal. Esto puede:
|
||||
|
||||
- Mejorar el rendimiento de un índice.
|
||||
|
||||
Si la clave principal es `(a, b)`, a continuación, añadir otra columna `c` mejorará el rendimiento si se cumplen las siguientes condiciones:
|
||||
|
||||
- Hay consultas con una condición en la columna `c`.
|
||||
- Rangos de datos largos (varias veces más `index_granularity`) con valores idénticos para `(a, b)` son comunes. En otras palabras, al agregar otra columna le permite omitir rangos de datos bastante largos.
|
||||
|
||||
- Mejorar la compresión de datos.
|
||||
|
||||
ClickHouse ordena los datos por clave principal, por lo que cuanto mayor sea la consistencia, mejor será la compresión.
|
||||
|
||||
- Proporcione una lógica adicional al fusionar partes de datos en el [ColapsarMergeTree](collapsingmergetree.md#table_engine-collapsingmergetree) y [SummingMergeTree](summingmergetree.md) motor.
|
||||
|
||||
En este caso tiene sentido especificar el *clave de clasificación* que es diferente de la clave principal.
|
||||
|
||||
Una clave principal larga afectará negativamente al rendimiento de la inserción y al consumo de memoria, pero las columnas adicionales de la clave principal no afectarán al rendimiento de ClickHouse durante `SELECT` consulta.
|
||||
|
||||
### Elegir una clave principal que difiere de la clave de ordenación {#choosing-a-primary-key-that-differs-from-the-sorting-key}
|
||||
|
||||
Es posible especificar una clave principal (una expresión con valores que se escriben en el archivo de índice para cada marca) que es diferente de la clave de ordenación (una expresión para ordenar las filas en partes de datos). En este caso, la tupla de expresión de clave primaria debe ser un prefijo de la tupla de expresión de clave de ordenación.
|
||||
|
||||
Esta característica es útil cuando se [SummingMergeTree](summingmergetree.md) y
|
||||
[AgregaciónMergeTree](aggregatingmergetree.md) motores de mesa. En un caso común cuando se utilizan estos motores, la tabla tiene dos tipos de columnas: *cota* y *medida*. Las consultas típicas agregan valores de columnas de medida con `GROUP BY` y filtrado por dimensiones. Debido a que SummingMergeTree y AggregatingMergeTree agregan filas con el mismo valor de la clave de ordenación, es natural agregarle todas las dimensiones. Como resultado, la expresión de clave consta de una larga lista de columnas y esta lista debe actualizarse con frecuencia con las dimensiones recién agregadas.
|
||||
|
||||
En este caso, tiene sentido dejar solo unas pocas columnas en la clave principal que proporcionarán análisis de rango eficientes y agregarán las columnas de dimensión restantes a la tupla de clave de clasificación.
|
||||
|
||||
[ALTER](../../../sql-reference/statements/alter.md) de la clave de ordenación es una operación ligera porque cuando se agrega una nueva columna simultáneamente a la tabla y a la clave de ordenación, las partes de datos existentes no necesitan ser cambiadas. Dado que la clave de ordenación anterior es un prefijo de la nueva clave de ordenación y no hay datos en la columna recién agregada, los datos se ordenan tanto por las claves de ordenación antiguas como por las nuevas en el momento de la modificación de la tabla.
|
||||
|
||||
### Uso de índices y particiones en consultas {#use-of-indexes-and-partitions-in-queries}
|
||||
|
||||
Para `SELECT` consultas, ClickHouse analiza si se puede usar un índice. Se puede usar un índice si el `WHERE/PREWHERE` clause tiene una expresión (como uno de los elementos de conjunción, o enteramente) que representa una operación de comparación de igualdad o desigualdad, o si tiene `IN` o `LIKE` con un prefijo fijo en columnas o expresiones que están en la clave principal o clave de partición, o en ciertas funciones parcialmente repetitivas de estas columnas, o relaciones lógicas de estas expresiones.
|
||||
|
||||
Por lo tanto, es posible ejecutar rápidamente consultas en uno o varios rangos de la clave principal. En este ejemplo, las consultas serán rápidas cuando se ejecuten para una etiqueta de seguimiento específica, para una etiqueta y un intervalo de fechas específicos, para una etiqueta y una fecha específicas, para varias etiquetas con un intervalo de fechas, etc.
|
||||
|
||||
Veamos el motor configurado de la siguiente manera:
|
||||
|
||||
ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate) SETTINGS index_granularity=8192
|
||||
|
||||
En este caso, en consultas:
|
||||
|
||||
``` sql
|
||||
SELECT count() FROM table WHERE EventDate = toDate(now()) AND CounterID = 34
|
||||
SELECT count() FROM table WHERE EventDate = toDate(now()) AND (CounterID = 34 OR CounterID = 42)
|
||||
SELECT count() FROM table WHERE ((EventDate >= toDate('2014-01-01') AND EventDate <= toDate('2014-01-31')) OR EventDate = toDate('2014-05-01')) AND CounterID IN (101500, 731962, 160656) AND (CounterID = 101500 OR EventDate != toDate('2014-05-01'))
|
||||
```
|
||||
|
||||
ClickHouse utilizará el índice de clave principal para recortar datos incorrectos y la clave de partición mensual para recortar particiones que están en intervalos de fechas incorrectos.
|
||||
|
||||
Las consultas anteriores muestran que el índice se usa incluso para expresiones complejas. La lectura de la tabla está organizada de modo que el uso del índice no puede ser más lento que un escaneo completo.
|
||||
|
||||
En el siguiente ejemplo, el índice no se puede usar.
|
||||
|
||||
``` sql
|
||||
SELECT count() FROM table WHERE CounterID = 34 OR URL LIKE '%upyachka%'
|
||||
```
|
||||
|
||||
Para comprobar si ClickHouse puede usar el índice al ejecutar una consulta, use la configuración [Fecha de nacimiento](../../../operations/settings/settings.md#settings-force_index_by_date) y [force_primary_key](../../../operations/settings/settings.md).
|
||||
|
||||
La clave para particionar por mes permite leer solo aquellos bloques de datos que contienen fechas del rango adecuado. En este caso, el bloque de datos puede contener datos para muchas fechas (hasta un mes). Dentro de un bloque, los datos se ordenan por clave principal, que puede no contener la fecha como la primera columna. Debido a esto, el uso de una consulta con solo una condición de fecha que no especifica el prefijo de clave principal hará que se lean más datos que para una sola fecha.
|
||||
|
||||
### Uso del índice para claves primarias parcialmente monótonas {#use-of-index-for-partially-monotonic-primary-keys}
|
||||
|
||||
Considere, por ejemplo, los días del mes. Ellos forman un [monótona secuencia](https://en.wikipedia.org/wiki/Monotonic_function) durante un mes, pero no monótono durante períodos más prolongados. Esta es una secuencia parcialmente monotónica. Si un usuario crea la tabla con clave primaria parcialmente monótona, ClickHouse crea un índice disperso como de costumbre. Cuando un usuario selecciona datos de este tipo de tabla, ClickHouse analiza las condiciones de consulta. Si el usuario desea obtener datos entre dos marcas del índice y ambas marcas caen dentro de un mes, ClickHouse puede usar el índice en este caso particular porque puede calcular la distancia entre los parámetros de una consulta y las marcas de índice.
|
||||
|
||||
ClickHouse no puede usar un índice si los valores de la clave principal en el rango de parámetros de consulta no representan una secuencia monotónica. En este caso, ClickHouse utiliza el método de análisis completo.
|
||||
|
||||
ClickHouse usa esta lógica no solo para secuencias de días del mes, sino para cualquier clave principal que represente una secuencia parcialmente monotónica.
|
||||
|
||||
### Índices de saltos de datos (experimental) {#table_engine-mergetree-data_skipping-indexes}
|
||||
|
||||
La declaración de índice se encuentra en la sección de columnas del `CREATE` consulta.
|
||||
|
||||
``` sql
|
||||
INDEX index_name expr TYPE type(...) GRANULARITY granularity_value
|
||||
```
|
||||
|
||||
Para tablas de la `*MergeTree` familia, se pueden especificar índices de omisión de datos.
|
||||
|
||||
Estos índices agregan cierta información sobre la expresión especificada en bloques, que consisten en `granularity_value` gránulos (el tamaño del gránulo se especifica utilizando el `index_granularity` ajuste en el motor de la tabla). Entonces estos agregados se usan en `SELECT` consultas para reducir la cantidad de datos a leer desde el disco omitiendo grandes bloques de datos donde el `where` consulta no puede ser satisfecha.
|
||||
|
||||
**Ejemplo**
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_name
|
||||
(
|
||||
u64 UInt64,
|
||||
i32 Int32,
|
||||
s String,
|
||||
...
|
||||
INDEX a (u64 * i32, s) TYPE minmax GRANULARITY 3,
|
||||
INDEX b (u64 * length(s)) TYPE set(1000) GRANULARITY 4
|
||||
) ENGINE = MergeTree()
|
||||
...
|
||||
```
|
||||
|
||||
ClickHouse puede utilizar los índices del ejemplo para reducir la cantidad de datos que se leen desde el disco en las siguientes consultas:
|
||||
|
||||
``` sql
|
||||
SELECT count() FROM table WHERE s < 'z'
|
||||
SELECT count() FROM table WHERE u64 * i32 == 10 AND u64 * length(s) >= 1234
|
||||
```
|
||||
|
||||
#### Tipos de índices disponibles {#available-types-of-indices}
|
||||
|
||||
- `minmax`
|
||||
|
||||
Almacena los extremos de la expresión especificada (si la expresión `tuple`, entonces almacena extremos para cada elemento de `tuple`), utiliza información almacenada para omitir bloques de datos como la clave principal.
|
||||
|
||||
- `set(max_rows)`
|
||||
|
||||
Almacena valores únicos de la expresión especificada (no más de `max_rows` filas, `max_rows=0` medio “no limits”). Utiliza los valores para comprobar si `WHERE` expresión no es satisfactorio en un bloque de datos.
|
||||
|
||||
- `ngrambf_v1(n, size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)`
|
||||
|
||||
Tiendas a [Filtro de floración](https://en.wikipedia.org/wiki/Bloom_filter) que contiene todos los ngrams de un bloque de datos. Funciona solo con cadenas. Puede ser utilizado para la optimización de `equals`, `like` y `in` expresiones.
|
||||
|
||||
- `n` — ngram size,
|
||||
- `size_of_bloom_filter_in_bytes` — Bloom filter size in bytes (you can use large values here, for example, 256 or 512, because it can be compressed well).
|
||||
- `number_of_hash_functions` — The number of hash functions used in the Bloom filter.
|
||||
- `random_seed` — The seed for Bloom filter hash functions.
|
||||
|
||||
- `tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)`
|
||||
|
||||
Lo mismo que `ngrambf_v1`, pero almacena tokens en lugar de ngrams. Los tokens son secuencias separadas por caracteres no alfanuméricos.
|
||||
|
||||
- `bloom_filter([false_positive])` — Stores a [Filtro de floración](https://en.wikipedia.org/wiki/Bloom_filter) para las columnas especificadas.
|
||||
|
||||
Opcional `false_positive` parámetro es la probabilidad de recibir una respuesta falsa positiva del filtro. Valores posibles: (0, 1). Valor predeterminado: 0.025.
|
||||
|
||||
Tipos de datos admitidos: `Int*`, `UInt*`, `Float*`, `Enum`, `Date`, `DateTime`, `String`, `FixedString`, `Array`, `LowCardinality`, `Nullable`.
|
||||
|
||||
Las siguientes funciones pueden usarlo: [igual](../../../sql-reference/functions/comparison-functions.md), [notEquals](../../../sql-reference/functions/comparison-functions.md), [en](../../../sql-reference/functions/in-functions.md), [noEn](../../../sql-reference/functions/in-functions.md), [tener](../../../sql-reference/functions/array-functions.md).
|
||||
|
||||
<!-- -->
|
||||
|
||||
``` sql
|
||||
INDEX sample_index (u64 * length(s)) TYPE minmax GRANULARITY 4
|
||||
INDEX sample_index2 (u64 * length(str), i32 + f64 * 100, date, str) TYPE set(100) GRANULARITY 4
|
||||
INDEX sample_index3 (lower(str), str) TYPE ngrambf_v1(3, 256, 2, 0) GRANULARITY 4
|
||||
```
|
||||
|
||||
#### Funciones de apoyo {#functions-support}
|
||||
|
||||
Condiciones en el `WHERE` cláusula contiene llamadas de las funciones que operan con columnas. Si la columna forma parte de un índice, ClickHouse intenta usar este índice al realizar las funciones. ClickHouse admite diferentes subconjuntos de funciones para usar índices.
|
||||
|
||||
El `set` index se puede utilizar con todas las funciones. Subconjuntos de funciones para otros índices se muestran en la siguiente tabla.
|
||||
|
||||
| Función (operador) / Índice | clave primaria | minmax | Descripción | Sistema abierto. | bloom_filter |
|
||||
|----------------------------------------------------------------------------------------------------------|----------------|--------|-------------|------------------|---------------|
|
||||
| [igual (=, ==)](../../../sql-reference/functions/comparison-functions.md#function-equals) | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
| [notEquals(!=, \<\>)](../../../sql-reference/functions/comparison-functions.md#function-notequals) | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
| [como](../../../sql-reference/functions/string-search-functions.md#function-like) | ✔ | ✔ | ✔ | ✗ | ✗ |
|
||||
| [No como](../../../sql-reference/functions/string-search-functions.md#function-notlike) | ✔ | ✔ | ✔ | ✗ | ✗ |
|
||||
| [Comienza con](../../../sql-reference/functions/string-functions.md#startswith) | ✔ | ✔ | ✔ | ✔ | ✗ |
|
||||
| [Finaliza con](../../../sql-reference/functions/string-functions.md#endswith) | ✗ | ✗ | ✔ | ✔ | ✗ |
|
||||
| [multiSearchAny](../../../sql-reference/functions/string-search-functions.md#function-multisearchany) | ✗ | ✗ | ✔ | ✗ | ✗ |
|
||||
| [en](../../../sql-reference/functions/in-functions.md#in-functions) | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
| [noEn](../../../sql-reference/functions/in-functions.md#in-functions) | ✔ | ✔ | ✔ | ✔ | ✔ |
|
||||
| [menos (\<)](../../../sql-reference/functions/comparison-functions.md#function-less) | ✔ | ✔ | ✗ | ✗ | ✗ |
|
||||
| [mayor (\>)](../../../sql-reference/functions/comparison-functions.md#function-greater) | ✔ | ✔ | ✗ | ✗ | ✗ |
|
||||
| [menosOrEquals (\<=)](../../../sql-reference/functions/comparison-functions.md#function-lessorequals) | ✔ | ✔ | ✗ | ✗ | ✗ |
|
||||
| [mayorOrEquals (\>=)](../../../sql-reference/functions/comparison-functions.md#function-greaterorequals) | ✔ | ✔ | ✗ | ✗ | ✗ |
|
||||
| [vaciar](../../../sql-reference/functions/array-functions.md#function-empty) | ✔ | ✔ | ✗ | ✗ | ✗ |
|
||||
| [notEmpty](../../../sql-reference/functions/array-functions.md#function-notempty) | ✔ | ✔ | ✗ | ✗ | ✗ |
|
||||
| hasToken | ✗ | ✗ | ✗ | ✔ | ✗ |
|
||||
|
||||
Las funciones con un argumento constante que es menor que el tamaño de ngram no pueden ser utilizadas por `ngrambf_v1` para la optimización de consultas.
|
||||
|
||||
Los filtros Bloom pueden tener coincidencias falsas positivas, por lo que `ngrambf_v1`, `tokenbf_v1`, y `bloom_filter` los índices no se pueden usar para optimizar consultas donde se espera que el resultado de una función sea falso, por ejemplo:
|
||||
|
||||
- Puede ser optimizado:
|
||||
- `s LIKE '%test%'`
|
||||
- `NOT s NOT LIKE '%test%'`
|
||||
- `s = 1`
|
||||
- `NOT s != 1`
|
||||
- `startsWith(s, 'test')`
|
||||
- No se puede optimizar:
|
||||
- `NOT s LIKE '%test%'`
|
||||
- `s NOT LIKE '%test%'`
|
||||
- `NOT s = 1`
|
||||
- `s != 1`
|
||||
- `NOT startsWith(s, 'test')`
|
||||
|
||||
## Acceso a datos simultáneos {#concurrent-data-access}
|
||||
|
||||
Para el acceso simultáneo a tablas, usamos versiones múltiples. En otras palabras, cuando una tabla se lee y actualiza simultáneamente, los datos se leen de un conjunto de partes que está actualizado en el momento de la consulta. No hay cerraduras largas. Las inserciones no se interponen en el camino de las operaciones de lectura.
|
||||
|
||||
La lectura de una tabla se paralela automáticamente.
|
||||
|
||||
## TTL para columnas y tablas {#table_engine-mergetree-ttl}
|
||||
|
||||
Determina la duración de los valores.
|
||||
|
||||
El `TTL` se puede establecer para toda la tabla y para cada columna individual. TTL de nivel de tabla también puede especificar la lógica de movimiento automático de datos entre discos y volúmenes.
|
||||
|
||||
Las expresiones deben evaluar [Fecha](../../../sql-reference/data-types/date.md) o [FechaHora](../../../sql-reference/data-types/datetime.md) tipo de datos.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` sql
|
||||
TTL time_column
|
||||
TTL time_column + interval
|
||||
```
|
||||
|
||||
Definir `interval`, utilizar [intervalo de tiempo](../../../sql-reference/operators/index.md#operators-datetime) operador.
|
||||
|
||||
``` sql
|
||||
TTL date_time + INTERVAL 1 MONTH
|
||||
TTL date_time + INTERVAL 15 HOUR
|
||||
```
|
||||
|
||||
### Columna TTL {#mergetree-column-ttl}
|
||||
|
||||
Cuando los valores de la columna caducan, ClickHouse los reemplaza con los valores predeterminados para el tipo de datos de columna. Si todos los valores de columna en la parte de datos caducan, ClickHouse elimina esta columna de la parte de datos en un sistema de archivos.
|
||||
|
||||
El `TTL` cláusula no se puede utilizar para columnas clave.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
Creación de una tabla con TTL
|
||||
|
||||
``` sql
|
||||
CREATE TABLE example_table
|
||||
(
|
||||
d DateTime,
|
||||
a Int TTL d + INTERVAL 1 MONTH,
|
||||
b Int TTL d + INTERVAL 1 MONTH,
|
||||
c String
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
PARTITION BY toYYYYMM(d)
|
||||
ORDER BY d;
|
||||
```
|
||||
|
||||
Adición de TTL a una columna de una tabla existente
|
||||
|
||||
``` sql
|
||||
ALTER TABLE example_table
|
||||
MODIFY COLUMN
|
||||
c String TTL d + INTERVAL 1 DAY;
|
||||
```
|
||||
|
||||
Modificación de TTL de la columna
|
||||
|
||||
``` sql
|
||||
ALTER TABLE example_table
|
||||
MODIFY COLUMN
|
||||
c String TTL d + INTERVAL 1 MONTH;
|
||||
```
|
||||
|
||||
### Tabla TTL {#mergetree-table-ttl}
|
||||
|
||||
La tabla puede tener una expresión para la eliminación de filas caducadas y varias expresiones para el movimiento automático de partes entre [discos o volúmenes](#table_engine-mergetree-multiple-volumes). Cuando las filas de la tabla caducan, ClickHouse elimina todas las filas correspondientes. Para la entidad de movimiento de piezas, todas las filas de una pieza deben cumplir los criterios de expresión de movimiento.
|
||||
|
||||
``` sql
|
||||
TTL expr [DELETE|TO DISK 'aaa'|TO VOLUME 'bbb'], ...
|
||||
```
|
||||
|
||||
El tipo de regla TTL puede seguir cada expresión TTL. Afecta a una acción que debe realizarse una vez que se satisface la expresión (alcanza la hora actual):
|
||||
|
||||
- `DELETE` - Eliminar filas caducadas (acción predeterminada);
|
||||
- `TO DISK 'aaa'` - mover parte al disco `aaa`;
|
||||
- `TO VOLUME 'bbb'` - mover parte al disco `bbb`.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
Creación de una tabla con TTL
|
||||
|
||||
``` sql
|
||||
CREATE TABLE example_table
|
||||
(
|
||||
d DateTime,
|
||||
a Int
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
PARTITION BY toYYYYMM(d)
|
||||
ORDER BY d
|
||||
TTL d + INTERVAL 1 MONTH [DELETE],
|
||||
d + INTERVAL 1 WEEK TO VOLUME 'aaa',
|
||||
d + INTERVAL 2 WEEK TO DISK 'bbb';
|
||||
```
|
||||
|
||||
Modificación de TTL de la tabla
|
||||
|
||||
``` sql
|
||||
ALTER TABLE example_table
|
||||
MODIFY TTL d + INTERVAL 1 DAY;
|
||||
```
|
||||
|
||||
**Eliminación de datos**
|
||||
|
||||
Los datos con un TTL caducado se eliminan cuando ClickHouse fusiona partes de datos.
|
||||
|
||||
Cuando ClickHouse ve que los datos han caducado, realiza una combinación fuera de programación. Para controlar la frecuencia de tales fusiones, puede establecer `merge_with_ttl_timeout`. Si el valor es demasiado bajo, realizará muchas fusiones fuera de horario que pueden consumir muchos recursos.
|
||||
|
||||
Si realiza el `SELECT` consulta entre fusiones, puede obtener datos caducados. Para evitarlo, use el [OPTIMIZE](../../../sql-reference/statements/misc.md#misc_operations-optimize) consulta antes `SELECT`.
|
||||
|
||||
## Uso de varios dispositivos de bloque para el almacenamiento de datos {#table_engine-mergetree-multiple-volumes}
|
||||
|
||||
### Implantación {#introduction}
|
||||
|
||||
`MergeTree` Los motores de tablas familiares pueden almacenar datos en múltiples dispositivos de bloque. Por ejemplo, puede ser útil cuando los datos de una determinada tabla se dividen implícitamente en “hot” y “cold”. Los datos más recientes se solicitan regularmente, pero solo requieren una pequeña cantidad de espacio. Por el contrario, los datos históricos de cola gorda se solicitan raramente. Si hay varios discos disponibles, el “hot” los datos pueden estar ubicados en discos rápidos (por ejemplo, SSD NVMe o en memoria), mientras que “cold” datos - en los relativamente lentos (por ejemplo, HDD).
|
||||
|
||||
La parte de datos es la unidad móvil mínima para `MergeTree`-mesas de motor. Los datos que pertenecen a una parte se almacenan en un disco. Las partes de datos se pueden mover entre discos en segundo plano (según la configuración del usuario) así como por medio de la [ALTER](../../../sql-reference/statements/alter.md#alter_move-partition) consulta.
|
||||
|
||||
### Plazo {#terms}
|
||||
|
||||
- Disk — Block device mounted to the filesystem.
|
||||
- Default disk — Disk that stores the path specified in the [camino](../../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-path) configuración del servidor.
|
||||
- Volume — Ordered set of equal disks (similar to [JBOD](https://en.wikipedia.org/wiki/Non-RAID_drive_architectures)).
|
||||
- Storage policy — Set of volumes and the rules for moving data between them.
|
||||
|
||||
Los nombres dados a las entidades descritas se pueden encontrar en las tablas del sistema, [sistema.almacenamiento_policies](../../../operations/system-tables.md#system_tables-storage_policies) y [sistema.disco](../../../operations/system-tables.md#system_tables-disks). Para aplicar una de las directivas de almacenamiento configuradas para una tabla, `storage_policy` establecimiento de `MergeTree`-mesas de la familia del motor.
|
||||
|
||||
### Configuración {#table_engine-mergetree-multiple-volumes_configure}
|
||||
|
||||
Los discos, los volúmenes y las políticas de almacenamiento deben declararse `<storage_configuration>` etiqueta ya sea en el archivo principal `config.xml` o en un archivo distinto en el `config.d` directorio.
|
||||
|
||||
Estructura de configuración:
|
||||
|
||||
``` xml
|
||||
<storage_configuration>
|
||||
<disks>
|
||||
<disk_name_1> <!-- disk name -->
|
||||
<path>/mnt/fast_ssd/clickhouse/</path>
|
||||
</disk_name_1>
|
||||
<disk_name_2>
|
||||
<path>/mnt/hdd1/clickhouse/</path>
|
||||
<keep_free_space_bytes>10485760</keep_free_space_bytes>
|
||||
</disk_name_2>
|
||||
<disk_name_3>
|
||||
<path>/mnt/hdd2/clickhouse/</path>
|
||||
<keep_free_space_bytes>10485760</keep_free_space_bytes>
|
||||
</disk_name_3>
|
||||
|
||||
...
|
||||
</disks>
|
||||
|
||||
...
|
||||
</storage_configuration>
|
||||
```
|
||||
|
||||
Tags:
|
||||
|
||||
- `<disk_name_N>` — Disk name. Names must be different for all disks.
|
||||
- `path` — path under which a server will store data (`data` y `shadow` carpetas), debe terminarse con ‘/’.
|
||||
- `keep_free_space_bytes` — the amount of free disk space to be reserved.
|
||||
|
||||
El orden de la definición del disco no es importante.
|
||||
|
||||
Marcado de configuración de directivas de almacenamiento:
|
||||
|
||||
``` xml
|
||||
<storage_configuration>
|
||||
...
|
||||
<policies>
|
||||
<policy_name_1>
|
||||
<volumes>
|
||||
<volume_name_1>
|
||||
<disk>disk_name_from_disks_configuration</disk>
|
||||
<max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
|
||||
</volume_name_1>
|
||||
<volume_name_2>
|
||||
<!-- configuration -->
|
||||
</volume_name_2>
|
||||
<!-- more volumes -->
|
||||
</volumes>
|
||||
<move_factor>0.2</move_factor>
|
||||
</policy_name_1>
|
||||
<policy_name_2>
|
||||
<!-- configuration -->
|
||||
</policy_name_2>
|
||||
|
||||
<!-- more policies -->
|
||||
</policies>
|
||||
...
|
||||
</storage_configuration>
|
||||
```
|
||||
|
||||
Tags:
|
||||
|
||||
- `policy_name_N` — Policy name. Policy names must be unique.
|
||||
- `volume_name_N` — Volume name. Volume names must be unique.
|
||||
- `disk` — a disk within a volume.
|
||||
- `max_data_part_size_bytes` — the maximum size of a part that can be stored on any of the volume's disks.
|
||||
- `move_factor` — when the amount of available space gets lower than this factor, data automatically start to move on the next volume if any (by default, 0.1).
|
||||
|
||||
Cofiguration ejemplos:
|
||||
|
||||
``` xml
|
||||
<storage_configuration>
|
||||
...
|
||||
<policies>
|
||||
<hdd_in_order> <!-- policy name -->
|
||||
<volumes>
|
||||
<single> <!-- volume name -->
|
||||
<disk>disk1</disk>
|
||||
<disk>disk2</disk>
|
||||
</single>
|
||||
</volumes>
|
||||
</hdd_in_order>
|
||||
|
||||
<moving_from_ssd_to_hdd>
|
||||
<volumes>
|
||||
<hot>
|
||||
<disk>fast_ssd</disk>
|
||||
<max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
|
||||
</hot>
|
||||
<cold>
|
||||
<disk>disk1</disk>
|
||||
</cold>
|
||||
</volumes>
|
||||
<move_factor>0.2</move_factor>
|
||||
</moving_from_ssd_to_hdd>
|
||||
</policies>
|
||||
...
|
||||
</storage_configuration>
|
||||
```
|
||||
|
||||
En un ejemplo dado, el `hdd_in_order` la política implementa el [Ronda-robin](https://en.wikipedia.org/wiki/Round-robin_scheduling) enfoque. Por lo tanto, esta política define solo un volumen (`single`), las partes de datos se almacenan en todos sus discos en orden circular. Dicha política puede ser bastante útil si hay varios discos similares montados en el sistema, pero RAID no está configurado. Tenga en cuenta que cada unidad de disco individual no es confiable y es posible que desee compensarlo con un factor de replicación de 3 o más.
|
||||
|
||||
Si hay diferentes tipos de discos disponibles en el sistema, `moving_from_ssd_to_hdd` política se puede utilizar en su lugar. Volumen `hot` consta de un disco SSD (`fast_ssd`), y el tamaño máximo de una pieza que se puede almacenar en este volumen es de 1 GB. Todas las piezas con el tamaño más grande que 1GB serán almacenadas directamente en `cold` volumen, que contiene un disco duro `disk1`.
|
||||
Además, una vez que el disco `fast_ssd` se llena en más del 80%, los datos se transferirán al `disk1` por un proceso en segundo plano.
|
||||
|
||||
El orden de enumeración de volúmenes dentro de una directiva de almacenamiento es importante. Una vez que un volumen está sobrellenado, los datos se mueven al siguiente. El orden de la enumeración del disco también es importante porque los datos se almacenan en ellos por turnos.
|
||||
|
||||
Al crear una tabla, se puede aplicarle una de las directivas de almacenamiento configuradas:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_with_non_default_policy (
|
||||
EventDate Date,
|
||||
OrderID UInt64,
|
||||
BannerID UInt64,
|
||||
SearchPhrase String
|
||||
) ENGINE = MergeTree
|
||||
ORDER BY (OrderID, BannerID)
|
||||
PARTITION BY toYYYYMM(EventDate)
|
||||
SETTINGS storage_policy = 'moving_from_ssd_to_hdd'
|
||||
```
|
||||
|
||||
El `default` política de almacenamiento implica el uso de un solo volumen, que consiste en un solo disco dado en `<path>`. Una vez que se crea una tabla, no se puede cambiar su política de almacenamiento.
|
||||
|
||||
### Detalles {#details}
|
||||
|
||||
En el caso de `MergeTree` tablas, los datos están llegando al disco de diferentes maneras:
|
||||
|
||||
- Como resultado de un inserto (`INSERT` consulta).
|
||||
- Durante las fusiones de fondo y [mutación](../../../sql-reference/statements/alter.md#alter-mutations).
|
||||
- Al descargar desde otra réplica.
|
||||
- Como resultado de la congelación de particiones [ALTER TABLE … FREEZE PARTITION](../../../sql-reference/statements/alter.md#alter_freeze-partition).
|
||||
|
||||
En todos estos casos, excepto las mutaciones y la congelación de particiones, una pieza se almacena en un volumen y un disco de acuerdo con la política de almacenamiento dada:
|
||||
|
||||
1. El primer volumen (en el orden de definición) que tiene suficiente espacio en disco para almacenar una pieza (`unreserved_space > current_part_size`) y permite almacenar partes de un tamaño determinado (`max_data_part_size_bytes > current_part_size`) se elige.
|
||||
2. Dentro de este volumen, se elige ese disco que sigue al que se utilizó para almacenar el fragmento de datos anterior y que tiene espacio libre más que el tamaño de la pieza (`unreserved_space - keep_free_space_bytes > current_part_size`).
|
||||
|
||||
Bajo el capó, las mutaciones y la congelación de particiones hacen uso de [enlaces duros](https://en.wikipedia.org/wiki/Hard_link). Los enlaces duros entre diferentes discos no son compatibles, por lo tanto, en tales casos las partes resultantes se almacenan en los mismos discos que los iniciales.
|
||||
|
||||
En el fondo, las partes se mueven entre volúmenes en función de la cantidad de espacio libre (`move_factor` parámetro) según el orden en que se declaran los volúmenes en el archivo de configuración.
|
||||
Los datos nunca se transfieren desde el último y al primero. Uno puede usar tablas del sistema [sistema.part_log](../../../operations/system-tables.md#system_tables-part-log) (campo `type = MOVE_PART`) y [sistema.parte](../../../operations/system-tables.md#system_tables-parts) (campo `path` y `disk`) para monitorear movimientos de fondo. Además, la información detallada se puede encontrar en los registros del servidor.
|
||||
|
||||
El usuario puede forzar el movimiento de una pieza o una partición de un volumen a otro mediante la consulta [ALTER TABLE … MOVE PART\|PARTITION … TO VOLUME\|DISK …](../../../sql-reference/statements/alter.md#alter_move-partition), todas las restricciones para las operaciones en segundo plano se tienen en cuenta. La consulta inicia un movimiento por sí misma y no espera a que se completen las operaciones en segundo plano. El usuario recibirá un mensaje de error si no hay suficiente espacio libre disponible o si no se cumple alguna de las condiciones requeridas.
|
||||
|
||||
Mover datos no interfiere con la replicación de datos. Por lo tanto, se pueden especificar diferentes directivas de almacenamiento para la misma tabla en diferentes réplicas.
|
||||
|
||||
Después de la finalización de las fusiones y mutaciones de fondo, las partes viejas se eliminan solo después de un cierto período de tiempo (`old_parts_lifetime`).
|
||||
Durante este tiempo, no se mueven a otros volúmenes o discos. Por lo tanto, hasta que las partes finalmente se eliminen, aún se tienen en cuenta para la evaluación del espacio en disco ocupado.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/ru/operations/table_engines/mergetree/) <!--hide-->
|
@ -1,69 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 33
|
||||
toc_title: ReplacingMergeTree
|
||||
---
|
||||
|
||||
# ReplacingMergeTree {#replacingmergetree}
|
||||
|
||||
El motor difiere de [Método de codificación de datos:](mergetree.md#table_engines-mergetree) en que elimina las entradas duplicadas con el mismo valor de clave principal (o más exactamente, con el mismo [clave de clasificación](mergetree.md) valor).
|
||||
|
||||
La desduplicación de datos solo se produce durante una fusión. La fusión ocurre en segundo plano en un momento desconocido, por lo que no puede planificarla. Algunos de los datos pueden permanecer sin procesar. Aunque puede ejecutar una fusión no programada utilizando el `OPTIMIZE` consulta, no cuente con usarlo, porque el `OPTIMIZE` consulta leerá y escribirá una gran cantidad de datos.
|
||||
|
||||
Así, `ReplacingMergeTree` es adecuado para borrar datos duplicados en segundo plano para ahorrar espacio, pero no garantiza la ausencia de duplicados.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = ReplacingMergeTree([ver])
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[PRIMARY KEY expr]
|
||||
[SAMPLE BY expr]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Para obtener una descripción de los parámetros de solicitud, consulte [descripción de la solicitud](../../../sql-reference/statements/create.md).
|
||||
|
||||
**ReplacingMergeTree Parámetros**
|
||||
|
||||
- `ver` — column with version. Type `UInt*`, `Date` o `DateTime`. Parámetro opcional.
|
||||
|
||||
Al fusionar, `ReplacingMergeTree` de todas las filas con la misma clave primaria deja solo una:
|
||||
|
||||
- Último en la selección, si `ver` no establecido.
|
||||
- Con la versión máxima, si `ver` indicado.
|
||||
|
||||
**Cláusulas de consulta**
|
||||
|
||||
Al crear un `ReplacingMergeTree` mesa de la misma [clausula](mergetree.md) se requieren, como al crear un `MergeTree` tabla.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No use este método en proyectos nuevos y, si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE [=] ReplacingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, [ver])
|
||||
```
|
||||
|
||||
Todos los parámetros excepto `ver` el mismo significado que en `MergeTree`.
|
||||
|
||||
- `ver` - columna con la versión. Parámetro opcional. Para una descripción, vea el texto anterior.
|
||||
|
||||
</details>
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/replacingmergetree/) <!--hide-->
|
@ -1,218 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 31
|
||||
toc_title: "Replicaci\xF3n de datos"
|
||||
---
|
||||
|
||||
# Replicación de datos {#table_engines-replication}
|
||||
|
||||
La replicación solo se admite para tablas de la familia MergeTree:
|
||||
|
||||
- ReplicatedMergeTree
|
||||
- ReplicatedSummingMergeTree
|
||||
- ReplicatedReplacingMergeTree
|
||||
- ReplicatedAggregatingMergeTree
|
||||
- ReplicatedCollapsingMergeTree
|
||||
- ReplicatedVersionedCollapsingMergetree
|
||||
- ReplicatedGraphiteMergeTree
|
||||
|
||||
La replicación funciona a nivel de una tabla individual, no de todo el servidor. Un servidor puede almacenar tablas replicadas y no replicadas al mismo tiempo.
|
||||
|
||||
La replicación no depende de la fragmentación. Cada fragmento tiene su propia replicación independiente.
|
||||
|
||||
Datos comprimidos para `INSERT` y `ALTER` se replica (para obtener más información, consulte la documentación para [ALTER](../../../sql-reference/statements/alter.md#query_language_queries_alter)).
|
||||
|
||||
`CREATE`, `DROP`, `ATTACH`, `DETACH` y `RENAME` las consultas se ejecutan en un único servidor y no se replican:
|
||||
|
||||
- El `CREATE TABLE` query crea una nueva tabla replicable en el servidor donde se ejecuta la consulta. Si esta tabla ya existe en otros servidores, agrega una nueva réplica.
|
||||
- El `DROP TABLE` query elimina la réplica ubicada en el servidor donde se ejecuta la consulta.
|
||||
- El `RENAME` query cambia el nombre de la tabla en una de las réplicas. En otras palabras, las tablas replicadas pueden tener diferentes nombres en diferentes réplicas.
|
||||
|
||||
Uso de ClickHouse [Apache ZooKeeper](https://zookeeper.apache.org) para almacenar metainformación de réplicas. Utilice ZooKeeper versión 3.4.5 o posterior.
|
||||
|
||||
Para utilizar la replicación, establezca los parámetros [Zookeeper](../../../operations/server-configuration-parameters/settings.md#server-settings_zookeeper) sección de configuración del servidor.
|
||||
|
||||
!!! attention "Atención"
|
||||
No descuides la configuración de seguridad. ClickHouse soporta el `digest` [Esquema de ACL](https://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#sc_ZooKeeperAccessControl) del subsistema de seguridad ZooKeeper.
|
||||
|
||||
Ejemplo de configuración de las direcciones del clúster ZooKeeper:
|
||||
|
||||
``` xml
|
||||
<zookeeper>
|
||||
<node index="1">
|
||||
<host>example1</host>
|
||||
<port>2181</port>
|
||||
</node>
|
||||
<node index="2">
|
||||
<host>example2</host>
|
||||
<port>2181</port>
|
||||
</node>
|
||||
<node index="3">
|
||||
<host>example3</host>
|
||||
<port>2181</port>
|
||||
</node>
|
||||
</zookeeper>
|
||||
```
|
||||
|
||||
Puede especificar cualquier clúster ZooKeeper existente y el sistema utilizará un directorio en él para sus propios datos (el directorio se especifica al crear una tabla replicable).
|
||||
|
||||
Si ZooKeeper no está establecido en el archivo de configuración, no puede crear tablas replicadas y las tablas replicadas existentes serán de solo lectura.
|
||||
|
||||
ZooKeeper no se utiliza en `SELECT` consultas porque la replicación no afecta al rendimiento de `SELECT` y las consultas se ejecutan tan rápido como lo hacen para las tablas no replicadas. Al consultar tablas replicadas distribuidas, el comportamiento de ClickHouse se controla mediante la configuración [max_replica_delay_for_distributed_queries](../../../operations/settings/settings.md#settings-max_replica_delay_for_distributed_queries) y [fallback_to_stale_replicas_for_distributed_queries](../../../operations/settings/settings.md#settings-fallback_to_stale_replicas_for_distributed_queries).
|
||||
|
||||
Para cada `INSERT` consulta, aproximadamente diez entradas se agregan a ZooKeeper a través de varias transacciones. (Para ser más precisos, esto es para cada bloque de datos insertado; una consulta INSERT contiene un bloque o un bloque por `max_insert_block_size = 1048576` filas.) Esto conduce a latencias ligeramente más largas para `INSERT` en comparación con las tablas no replicadas. Pero si sigue las recomendaciones para insertar datos en lotes de no más de uno `INSERT` por segundo, no crea ningún problema. Todo el clúster ClickHouse utilizado para coordinar un clúster ZooKeeper tiene un total de varios cientos `INSERTs` por segundo. El rendimiento en las inserciones de datos (el número de filas por segundo) es tan alto como para los datos no replicados.
|
||||
|
||||
Para clústeres muy grandes, puede usar diferentes clústeres de ZooKeeper para diferentes fragmentos. Sin embargo, esto no ha demostrado ser necesario en el Yandex.Clúster Metrica (aproximadamente 300 servidores).
|
||||
|
||||
La replicación es asíncrona y multi-master. `INSERT` consultas (así como `ALTER`) se puede enviar a cualquier servidor disponible. Los datos se insertan en el servidor donde se ejecuta la consulta y, a continuación, se copian a los demás servidores. Debido a que es asincrónico, los datos insertados recientemente aparecen en las otras réplicas con cierta latencia. Si parte de las réplicas no está disponible, los datos se escriben cuando estén disponibles. Si hay una réplica disponible, la latencia es la cantidad de tiempo que tarda en transferir el bloque de datos comprimidos a través de la red.
|
||||
|
||||
De forma predeterminada, una consulta INSERT espera la confirmación de la escritura de los datos de una sola réplica. Si los datos fue correctamente escrito a sólo una réplica y el servidor con esta réplica deja de existir, los datos almacenados se perderán. Para habilitar la confirmación de las escrituras de datos de varias réplicas, utilice `insert_quorum` opcion.
|
||||
|
||||
Cada bloque de datos se escribe atómicamente. La consulta INSERT se divide en bloques hasta `max_insert_block_size = 1048576` filas. En otras palabras, si el `INSERT` consulta tiene menos de 1048576 filas, se hace atómicamente.
|
||||
|
||||
Los bloques de datos se deduplican. Para varias escrituras del mismo bloque de datos (bloques de datos del mismo tamaño que contienen las mismas filas en el mismo orden), el bloque solo se escribe una vez. La razón de esto es en caso de fallas de red cuando la aplicación cliente no sabe si los datos se escribieron en la base de datos, por lo que `INSERT` consulta simplemente se puede repetir. No importa a qué réplica se enviaron los INSERT con datos idénticos. `INSERTs` son idempotentes. Los parámetros de desduplicación son controlados por [merge_tree](../../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-merge_tree) configuración del servidor.
|
||||
|
||||
Durante la replicación, sólo los datos de origen que se van a insertar se transfieren a través de la red. La transformación de datos adicional (fusión) se coordina y se realiza en todas las réplicas de la misma manera. Esto minimiza el uso de la red, lo que significa que la replicación funciona bien cuando las réplicas residen en centros de datos diferentes. (Tenga en cuenta que la duplicación de datos en diferentes centros de datos es el objetivo principal de la replicación.)
|
||||
|
||||
Puede tener cualquier número de réplicas de los mismos datos. El Yandex.Metrica utiliza doble replicación en producción. Cada servidor utiliza RAID-5 o RAID-6, y RAID-10 en algunos casos. Esta es una solución relativamente confiable y conveniente.
|
||||
|
||||
El sistema supervisa la sincronicidad de los datos en las réplicas y puede recuperarse después de un fallo. La conmutación por error es automática (para pequeñas diferencias en los datos) o semiautomática (cuando los datos difieren demasiado, lo que puede indicar un error de configuración).
|
||||
|
||||
## Creación de tablas replicadas {#creating-replicated-tables}
|
||||
|
||||
El `Replicated` prefijo se agrega al nombre del motor de tabla. Por ejemplo:`ReplicatedMergeTree`.
|
||||
|
||||
**Replicated\*MergeTree parámetros**
|
||||
|
||||
- `zoo_path` — The path to the table in ZooKeeper.
|
||||
- `replica_name` — The replica name in ZooKeeper.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_name
|
||||
(
|
||||
EventDate DateTime,
|
||||
CounterID UInt32,
|
||||
UserID UInt32
|
||||
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/table_name', '{replica}')
|
||||
PARTITION BY toYYYYMM(EventDate)
|
||||
ORDER BY (CounterID, EventDate, intHash32(UserID))
|
||||
SAMPLE BY intHash32(UserID)
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Ejemplo en sintaxis obsoleta</summary>
|
||||
|
||||
``` sql
|
||||
CREATE TABLE table_name
|
||||
(
|
||||
EventDate DateTime,
|
||||
CounterID UInt32,
|
||||
UserID UInt32
|
||||
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}/table_name', '{replica}', EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID), EventTime), 8192)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Como muestra el ejemplo, estos parámetros pueden contener sustituciones entre llaves. Los valores sustituidos se toman de la ‘macros’ sección del archivo de configuración. Ejemplo:
|
||||
|
||||
``` xml
|
||||
<macros>
|
||||
<layer>05</layer>
|
||||
<shard>02</shard>
|
||||
<replica>example05-02-1.yandex.ru</replica>
|
||||
</macros>
|
||||
```
|
||||
|
||||
La ruta de acceso a la tabla en ZooKeeper debe ser única para cada tabla replicada. Las tablas en diferentes fragmentos deben tener rutas diferentes.
|
||||
En este caso, la ruta consta de las siguientes partes:
|
||||
|
||||
`/clickhouse/tables/` es el prefijo común. Recomendamos usar exactamente este.
|
||||
|
||||
`{layer}-{shard}` es el identificador de fragmento. En este ejemplo consta de dos partes, ya que el Yandex.Metrica clúster utiliza sharding de dos niveles. Para la mayoría de las tareas, puede dejar solo la sustitución {shard}, que se expandirá al identificador de fragmento.
|
||||
|
||||
`table_name` es el nombre del nodo de la tabla en ZooKeeper. Es una buena idea hacerlo igual que el nombre de la tabla. Se define explícitamente, porque a diferencia del nombre de la tabla, no cambia después de una consulta RENAME.
|
||||
*HINT*: podría agregar un nombre de base de datos delante de `table_name` También. Nivel de Cifrado WEP `db_name.table_name`
|
||||
|
||||
El nombre de réplica identifica diferentes réplicas de la misma tabla. Puede usar el nombre del servidor para esto, como en el ejemplo. El nombre solo tiene que ser único dentro de cada fragmento.
|
||||
|
||||
Puede definir los parámetros explícitamente en lugar de utilizar sustituciones. Esto podría ser conveniente para probar y para configurar clústeres pequeños. Sin embargo, no puede usar consultas DDL distribuidas (`ON CLUSTER` en este caso.
|
||||
|
||||
Cuando se trabaja con clústeres grandes, se recomienda utilizar sustituciones porque reducen la probabilidad de error.
|
||||
|
||||
Ejecute el `CREATE TABLE` consulta en cada réplica. Esta consulta crea una nueva tabla replicada o agrega una nueva réplica a una existente.
|
||||
|
||||
Si agrega una nueva réplica después de que la tabla ya contenga algunos datos en otras réplicas, los datos se copiarán de las otras réplicas a la nueva después de ejecutar la consulta. En otras palabras, la nueva réplica se sincroniza con las demás.
|
||||
|
||||
Para eliminar una réplica, ejecute `DROP TABLE`. However, only one replica is deleted – the one that resides on the server where you run the query.
|
||||
|
||||
## Recuperación después de fallos {#recovery-after-failures}
|
||||
|
||||
Si ZooKeeper no está disponible cuando se inicia un servidor, las tablas replicadas cambian al modo de solo lectura. El sistema intenta conectarse periódicamente a ZooKeeper.
|
||||
|
||||
Si ZooKeeper no está disponible durante un `INSERT`, o se produce un error al interactuar con ZooKeeper, se produce una excepción.
|
||||
|
||||
Después de conectarse a ZooKeeper, el sistema comprueba si el conjunto de datos en el sistema de archivos local coincide con el conjunto de datos esperado (ZooKeeper almacena esta información). Si hay incoherencias menores, el sistema las resuelve sincronizando datos con las réplicas.
|
||||
|
||||
Si el sistema detecta partes de datos rotas (con un tamaño incorrecto de archivos) o partes no reconocidas (partes escritas en el sistema de archivos pero no grabadas en ZooKeeper), las mueve al `detached` subdirectorio (no se eliminan). Las piezas que faltan se copian de las réplicas.
|
||||
|
||||
Tenga en cuenta que ClickHouse no realiza ninguna acción destructiva, como eliminar automáticamente una gran cantidad de datos.
|
||||
|
||||
Cuando el servidor se inicia (o establece una nueva sesión con ZooKeeper), solo verifica la cantidad y el tamaño de todos los archivos. Si los tamaños de los archivos coinciden pero los bytes se han cambiado en algún punto intermedio, esto no se detecta inmediatamente, sino solo cuando se intenta leer los datos `SELECT` consulta. La consulta produce una excepción sobre una suma de comprobación no coincidente o el tamaño de un bloque comprimido. En este caso, las partes de datos se agregan a la cola de verificación y se copian de las réplicas si es necesario.
|
||||
|
||||
Si el conjunto local de datos difiere demasiado del esperado, se activa un mecanismo de seguridad. El servidor ingresa esto en el registro y se niega a iniciarse. La razón de esto es que este caso puede indicar un error de configuración, como si una réplica en un fragmento se configurara accidentalmente como una réplica en un fragmento diferente. Sin embargo, los umbrales para este mecanismo se establecen bastante bajos, y esta situación puede ocurrir durante la recuperación de falla normal. En este caso, los datos se restauran semiautomáticamente, mediante “pushing a button”.
|
||||
|
||||
Para iniciar la recuperación, cree el nodo `/path_to_table/replica_name/flags/force_restore_data` en ZooKeeper con cualquier contenido, o ejecute el comando para restaurar todas las tablas replicadas:
|
||||
|
||||
``` bash
|
||||
sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data
|
||||
```
|
||||
|
||||
A continuación, reinicie el servidor. Al iniciar, el servidor elimina estos indicadores e inicia la recuperación.
|
||||
|
||||
## Recuperación después de la pérdida completa de datos {#recovery-after-complete-data-loss}
|
||||
|
||||
Si todos los datos y metadatos desaparecieron de uno de los servidores, siga estos pasos para la recuperación:
|
||||
|
||||
1. Instale ClickHouse en el servidor. Defina correctamente las sustituciones en el archivo de configuración que contiene el identificador de fragmento y las réplicas, si las usa.
|
||||
2. Si tenía tablas no duplicadas que deben duplicarse manualmente en los servidores, copie sus datos desde una réplica (en el directorio `/var/lib/clickhouse/data/db_name/table_name/`).
|
||||
3. Copiar definiciones de tablas ubicadas en `/var/lib/clickhouse/metadata/` de una réplica. Si un identificador de fragmento o réplica se define explícitamente en las definiciones de tabla, corríjalo para que corresponda a esta réplica. (Como alternativa, inicie el servidor y `ATTACH TABLE` consultas que deberían haber estado en el .sql archivos en `/var/lib/clickhouse/metadata/`.)
|
||||
4. Para iniciar la recuperación, cree el nodo ZooKeeper `/path_to_table/replica_name/flags/force_restore_data` con cualquier contenido o ejecute el comando para restaurar todas las tablas replicadas: `sudo -u clickhouse touch /var/lib/clickhouse/flags/force_restore_data`
|
||||
|
||||
Luego inicie el servidor (reinicie, si ya se está ejecutando). Los datos se descargarán de las réplicas.
|
||||
|
||||
Una opción de recuperación alternativa es eliminar información sobre la réplica perdida de ZooKeeper (`/path_to_table/replica_name`), luego vuelva a crear la réplica como se describe en “[Creación de tablas replicadas](#creating-replicated-tables)”.
|
||||
|
||||
No hay restricción en el ancho de banda de la red durante la recuperación. Tenga esto en cuenta si está restaurando muchas réplicas a la vez.
|
||||
|
||||
## La conversión de MergeTree a ReplicatedMergeTree {#converting-from-mergetree-to-replicatedmergetree}
|
||||
|
||||
Usamos el término `MergeTree` para referirse a todos los motores de mesa en el `MergeTree family`, lo mismo que para `ReplicatedMergeTree`.
|
||||
|
||||
Si usted tenía un `MergeTree` tabla replicada manualmente, puede convertirla en una tabla replicada. Es posible que tenga que hacer esto si ya ha recopilado una gran cantidad de datos `MergeTree` y ahora desea habilitar la replicación.
|
||||
|
||||
Si los datos difieren en varias réplicas, primero sincronícelos o elimínelos en todas las réplicas, excepto en una.
|
||||
|
||||
Cambie el nombre de la tabla MergeTree existente y, a continuación, cree un `ReplicatedMergeTree` mesa con el antiguo nombre.
|
||||
Mueva los datos de la tabla antigua a la `detached` subdirectorio dentro del directorio con los nuevos datos de la tabla (`/var/lib/clickhouse/data/db_name/table_name/`).
|
||||
Luego ejecuta `ALTER TABLE ATTACH PARTITION` en una de las réplicas para agregar estas partes de datos al conjunto de trabajo.
|
||||
|
||||
## La conversión de ReplicatedMergeTree a MergeTree {#converting-from-replicatedmergetree-to-mergetree}
|
||||
|
||||
Cree una tabla MergeTree con un nombre diferente. Mueva todos los datos del directorio con el `ReplicatedMergeTree` datos de la tabla al directorio de datos de la nueva tabla. A continuación, elimine el `ReplicatedMergeTree` y reinicie el servidor.
|
||||
|
||||
Si desea deshacerse de un `ReplicatedMergeTree` sin iniciar el servidor:
|
||||
|
||||
- Eliminar el correspondiente `.sql` archivo en el directorio de metadatos (`/var/lib/clickhouse/metadata/`).
|
||||
- Eliminar la ruta correspondiente en ZooKeeper (`/path_to_table/replica_name`).
|
||||
|
||||
Después de esto, puede iniciar el servidor, crear un `MergeTree` tabla, mueva los datos a su directorio y, a continuación, reinicie el servidor.
|
||||
|
||||
## Recuperación cuando se pierden o se dañan los metadatos del clúster Zookeeper {#recovery-when-metadata-in-the-zookeeper-cluster-is-lost-or-damaged}
|
||||
|
||||
Si los datos de ZooKeeper se perdieron o se dañaron, puede guardar los datos moviéndolos a una tabla no duplicada como se describió anteriormente.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/replication/) <!--hide-->
|
@ -1,141 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 34
|
||||
toc_title: SummingMergeTree
|
||||
---
|
||||
|
||||
# SummingMergeTree {#summingmergetree}
|
||||
|
||||
El motor hereda de [Método de codificación de datos:](mergetree.md#table_engines-mergetree). La diferencia es que al fusionar partes de datos para `SummingMergeTree` ClickHouse reemplaza todas las filas con la misma clave primaria (o más exactamente, con la misma [clave de clasificación](mergetree.md)) con una fila que contiene valores resumidos para las columnas con el tipo de datos numérico. Si la clave de ordenación está compuesta de manera que un solo valor de clave corresponde a un gran número de filas, esto reduce significativamente el volumen de almacenamiento y acelera la selección de datos.
|
||||
|
||||
Recomendamos usar el motor junto con `MergeTree`. Almacenar datos completos en `MergeTree` mesa, y el uso `SummingMergeTree` para el almacenamiento de datos agregados, por ejemplo, al preparar informes. Tal enfoque evitará que pierda datos valiosos debido a una clave primaria compuesta incorrectamente.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = SummingMergeTree([columns])
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[SAMPLE BY expr]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Para obtener una descripción de los parámetros de solicitud, consulte [descripción de la solicitud](../../../sql-reference/statements/create.md).
|
||||
|
||||
**Parámetros de SummingMergeTree**
|
||||
|
||||
- `columns` - una tupla con los nombres de las columnas donde se resumirán los valores. Parámetro opcional.
|
||||
Las columnas deben ser de tipo numérico y no deben estar en la clave principal.
|
||||
|
||||
Si `columns` no especificado, ClickHouse resume los valores de todas las columnas con un tipo de datos numérico que no están en la clave principal.
|
||||
|
||||
**Cláusulas de consulta**
|
||||
|
||||
Al crear un `SummingMergeTree` mesa de la misma [clausula](mergetree.md) se requieren, como al crear un `MergeTree` tabla.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No use este método en proyectos nuevos y, si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE [=] SummingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, [columns])
|
||||
```
|
||||
|
||||
Todos los parámetros excepto `columns` el mismo significado que en `MergeTree`.
|
||||
|
||||
- `columns` — tuple with names of columns values of which will be summarized. Optional parameter. For a description, see the text above.
|
||||
|
||||
</details>
|
||||
|
||||
## Ejemplo de uso {#usage-example}
|
||||
|
||||
Considere la siguiente tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE summtt
|
||||
(
|
||||
key UInt32,
|
||||
value UInt32
|
||||
)
|
||||
ENGINE = SummingMergeTree()
|
||||
ORDER BY key
|
||||
```
|
||||
|
||||
Insertar datos:
|
||||
|
||||
``` sql
|
||||
INSERT INTO summtt Values(1,1),(1,2),(2,1)
|
||||
```
|
||||
|
||||
ClickHouse puede sumar todas las filas no completamente ([ver abajo](#data-processing)), entonces usamos una función agregada `sum` y `GROUP BY` cláusula en la consulta.
|
||||
|
||||
``` sql
|
||||
SELECT key, sum(value) FROM summtt GROUP BY key
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─key─┬─sum(value)─┐
|
||||
│ 2 │ 1 │
|
||||
│ 1 │ 3 │
|
||||
└─────┴────────────┘
|
||||
```
|
||||
|
||||
## Procesamiento de datos {#data-processing}
|
||||
|
||||
Cuando los datos se insertan en una tabla, se guardan tal cual. ClickHouse combina las partes insertadas de los datos periódicamente y esto es cuando las filas con la misma clave principal se suman y se reemplazan con una para cada parte resultante de los datos.
|
||||
|
||||
ClickHouse can merge the data parts so that different resulting parts of data cat consist rows with the same primary key, i.e. the summation will be incomplete. Therefore (`SELECT`) una función agregada [resumir()](../../../sql-reference/aggregate-functions/reference.md#agg_function-sum) y `GROUP BY` cláusula se debe utilizar en una consulta como se describe en el ejemplo anterior.
|
||||
|
||||
### Reglas comunes para la suma {#common-rules-for-summation}
|
||||
|
||||
Se resumen los valores de las columnas con el tipo de datos numérico. El conjunto de columnas está definido por el parámetro `columns`.
|
||||
|
||||
Si los valores eran 0 en todas las columnas para la suma, se elimina la fila.
|
||||
|
||||
Si la columna no está en la clave principal y no se resume, se selecciona un valor arbitrario entre los existentes.
|
||||
|
||||
Los valores no se resumen para las columnas de la clave principal.
|
||||
|
||||
### La suma en las columnas de función agregada {#the-summation-in-the-aggregatefunction-columns}
|
||||
|
||||
Para columnas de [Tipo AggregateFunction](../../../sql-reference/data-types/aggregatefunction.md) ClickHouse se comporta como [AgregaciónMergeTree](aggregatingmergetree.md) agregación del motor según la función.
|
||||
|
||||
### Estructuras anidadas {#nested-structures}
|
||||
|
||||
La tabla puede tener estructuras de datos anidadas que se procesan de una manera especial.
|
||||
|
||||
Si el nombre de una tabla anidada termina con `Map` y contiene al menos dos columnas que cumplen los siguientes criterios:
|
||||
|
||||
- la primera columna es numérica `(*Int*, Date, DateTime)` o una cadena `(String, FixedString)`, vamos a llamarlo `key`,
|
||||
- las otras columnas son aritméticas `(*Int*, Float32/64)`, vamos a llamarlo `(values...)`,
|
||||
|
||||
entonces esta tabla anidada se interpreta como una asignación de `key => (values...)`, y al fusionar sus filas, los elementos de dos conjuntos de datos se fusionan por `key` con una suma de los correspondientes `(values...)`.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
``` text
|
||||
[(1, 100)] + [(2, 150)] -> [(1, 100), (2, 150)]
|
||||
[(1, 100)] + [(1, 150)] -> [(1, 250)]
|
||||
[(1, 100)] + [(1, 150), (2, 150)] -> [(1, 250), (2, 150)]
|
||||
[(1, 100), (2, 150)] + [(1, -100)] -> [(2, 150)]
|
||||
```
|
||||
|
||||
Al solicitar datos, utilice el [sumMap(clave, valor)](../../../sql-reference/aggregate-functions/reference.md) función para la agregación de `Map`.
|
||||
|
||||
Para la estructura de datos anidados, no necesita especificar sus columnas en la tupla de columnas para la suma.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/summingmergetree/) <!--hide-->
|
@ -1,238 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 37
|
||||
toc_title: VersionedCollapsingMergeTree
|
||||
---
|
||||
|
||||
# VersionedCollapsingMergeTree {#versionedcollapsingmergetree}
|
||||
|
||||
Este motor:
|
||||
|
||||
- Permite la escritura rápida de estados de objetos que cambian continuamente.
|
||||
- Elimina los estados de objetos antiguos en segundo plano. Esto reduce significativamente el volumen de almacenamiento.
|
||||
|
||||
Vea la sección [Derrumbar](#table_engines_versionedcollapsingmergetree) para más detalles.
|
||||
|
||||
El motor hereda de [Método de codificación de datos:](mergetree.md#table_engines-mergetree) y agrega la lógica para colapsar filas al algoritmo para fusionar partes de datos. `VersionedCollapsingMergeTree` tiene el mismo propósito que [ColapsarMergeTree](collapsingmergetree.md) pero usa un algoritmo de colapso diferente que permite insertar los datos en cualquier orden con múltiples hilos. En particular, el `Version` columna ayuda a contraer las filas correctamente, incluso si se insertan en el orden incorrecto. En contraste, `CollapsingMergeTree` sólo permite la inserción estrictamente consecutiva.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE = VersionedCollapsingMergeTree(sign, version)
|
||||
[PARTITION BY expr]
|
||||
[ORDER BY expr]
|
||||
[SAMPLE BY expr]
|
||||
[SETTINGS name=value, ...]
|
||||
```
|
||||
|
||||
Para obtener una descripción de los parámetros de consulta, consulte [descripción de la consulta](../../../sql-reference/statements/create.md).
|
||||
|
||||
**Parámetros del motor**
|
||||
|
||||
``` sql
|
||||
VersionedCollapsingMergeTree(sign, version)
|
||||
```
|
||||
|
||||
- `sign` — Name of the column with the type of row: `1` es una “state” fila, `-1` es una “cancel” fila.
|
||||
|
||||
El tipo de datos de columna debe ser `Int8`.
|
||||
|
||||
- `version` — Name of the column with the version of the object state.
|
||||
|
||||
El tipo de datos de columna debe ser `UInt*`.
|
||||
|
||||
**Cláusulas de consulta**
|
||||
|
||||
Al crear un `VersionedCollapsingMergeTree` mesa, la misma [clausula](mergetree.md) se requieren como al crear un `MergeTree` tabla.
|
||||
|
||||
<details markdown="1">
|
||||
|
||||
<summary>Método obsoleto para crear una tabla</summary>
|
||||
|
||||
!!! attention "Atención"
|
||||
No utilice este método en nuevos proyectos. Si es posible, cambie los proyectos antiguos al método descrito anteriormente.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
|
||||
...
|
||||
) ENGINE [=] VersionedCollapsingMergeTree(date-column [, samp#table_engines_versionedcollapsingmergetreeling_expression], (primary, key), index_granularity, sign, version)
|
||||
```
|
||||
|
||||
Todos los parámetros excepto `sign` y `version` el mismo significado que en `MergeTree`.
|
||||
|
||||
- `sign` — Name of the column with the type of row: `1` es una “state” fila, `-1` es una “cancel” fila.
|
||||
|
||||
Column Data Type — `Int8`.
|
||||
|
||||
- `version` — Name of the column with the version of the object state.
|
||||
|
||||
El tipo de datos de columna debe ser `UInt*`.
|
||||
|
||||
</details>
|
||||
|
||||
## Derrumbar {#table_engines_versionedcollapsingmergetree}
|
||||
|
||||
### Datos {#data}
|
||||
|
||||
Considere una situación en la que necesite guardar datos que cambien continuamente para algún objeto. Es razonable tener una fila para un objeto y actualizar la fila siempre que haya cambios. Sin embargo, la operación de actualización es costosa y lenta para un DBMS porque requiere volver a escribir los datos en el almacenamiento. La actualización no es aceptable si necesita escribir datos rápidamente, pero puede escribir los cambios en un objeto secuencialmente de la siguiente manera.
|
||||
|
||||
Utilice el `Sign` columna al escribir la fila. Si `Sign = 1` significa que la fila es un estado de un objeto (llamémoslo el “state” fila). Si `Sign = -1` indica la cancelación del estado de un objeto con los mismos atributos (llamémoslo el “cancel” fila). También use el `Version` columna, que debe identificar cada estado de un objeto con un número separado.
|
||||
|
||||
Por ejemplo, queremos calcular cuántas páginas visitaron los usuarios en algún sitio y cuánto tiempo estuvieron allí. En algún momento escribimos la siguiente fila con el estado de la actividad del usuario:
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 |
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
```
|
||||
|
||||
En algún momento después registramos el cambio de actividad del usuario y lo escribimos con las siguientes dos filas.
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 |
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 |
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
```
|
||||
|
||||
La primera fila cancela el estado anterior del objeto (usuario). Debe copiar todos los campos del estado cancelado excepto `Sign`.
|
||||
|
||||
La segunda fila contiene el estado actual.
|
||||
|
||||
Debido a que solo necesitamos el último estado de actividad del usuario, las filas
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 |
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 |
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
```
|
||||
|
||||
se puede eliminar, colapsando el estado no válido (antiguo) del objeto. `VersionedCollapsingMergeTree` hace esto mientras fusiona las partes de datos.
|
||||
|
||||
Para averiguar por qué necesitamos dos filas para cada cambio, vea [Algoritmo](#table_engines-versionedcollapsingmergetree-algorithm).
|
||||
|
||||
**Notas sobre el uso**
|
||||
|
||||
1. El programa que escribe los datos debe recordar el estado de un objeto para cancelarlo. El “cancel” cadena debe ser una copia de la “state” con lo opuesto `Sign`. Esto aumenta el tamaño inicial de almacenamiento, pero permite escribir los datos rápidamente.
|
||||
2. Las matrices de largo crecimiento en columnas reducen la eficiencia del motor debido a la carga para escribir. Cuanto más sencillos sean los datos, mejor será la eficiencia.
|
||||
3. `SELECT` Los resultados dependen en gran medida de la coherencia del historial de cambios de objetos. Sea preciso al preparar los datos para insertarlos. Puede obtener resultados impredecibles con datos incoherentes, como valores negativos para métricas no negativas, como la profundidad de la sesión.
|
||||
|
||||
### Algoritmo {#table_engines-versionedcollapsingmergetree-algorithm}
|
||||
|
||||
Cuando ClickHouse combina partes de datos, elimina cada par de filas que tienen la misma clave principal y versión y diferentes `Sign`. El orden de las filas no importa.
|
||||
|
||||
Cuando ClickHouse inserta datos, ordena filas por la clave principal. Si el `Version` la columna no está en la clave principal, ClickHouse la agrega a la clave principal implícitamente como el último campo y la usa para ordenar.
|
||||
|
||||
## Selección de datos {#selecting-data}
|
||||
|
||||
ClickHouse no garantiza que todas las filas con la misma clave principal estén en la misma parte de datos resultante o incluso en el mismo servidor físico. Esto es cierto tanto para escribir los datos como para la posterior fusión de las partes de datos. Además, ClickHouse procesa `SELECT` consultas con múltiples subprocesos, y no puede predecir el orden de las filas en el resultado. Esto significa que la agregación es necesaria si hay una necesidad de obtener completamente “collapsed” datos de un `VersionedCollapsingMergeTree` tabla.
|
||||
|
||||
Para finalizar el colapso, escriba una consulta con un `GROUP BY` cláusula y funciones agregadas que representan el signo. Por ejemplo, para calcular la cantidad, use `sum(Sign)` en lugar de `count()`. Para calcular la suma de algo, use `sum(Sign * x)` en lugar de `sum(x)` y agregar `HAVING sum(Sign) > 0`.
|
||||
|
||||
Los agregados `count`, `sum` y `avg` se puede calcular de esta manera. El agregado `uniq` se puede calcular si un objeto tiene al menos un estado no colapsado. Los agregados `min` y `max` no se puede calcular porque `VersionedCollapsingMergeTree` no guarda el historial de valores de estados colapsados.
|
||||
|
||||
Si necesita extraer los datos con “collapsing” pero sin agregación (por ejemplo, para verificar si hay filas presentes cuyos valores más nuevos coinciden con ciertas condiciones), puede usar el `FINAL` modificador para el `FROM` clausula. Este enfoque es ineficiente y no debe usarse con tablas grandes.
|
||||
|
||||
## Ejemplo de uso {#example-of-use}
|
||||
|
||||
Datos de ejemplo:
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 |
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 |
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 |
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
```
|
||||
|
||||
Creación de la tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE UAct
|
||||
(
|
||||
UserID UInt64,
|
||||
PageViews UInt8,
|
||||
Duration UInt8,
|
||||
Sign Int8,
|
||||
Version UInt8
|
||||
)
|
||||
ENGINE = VersionedCollapsingMergeTree(Sign, Version)
|
||||
ORDER BY UserID
|
||||
```
|
||||
|
||||
Insertar los datos:
|
||||
|
||||
``` sql
|
||||
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, 1, 1)
|
||||
```
|
||||
|
||||
``` sql
|
||||
INSERT INTO UAct VALUES (4324182021466249494, 5, 146, -1, 1),(4324182021466249494, 6, 185, 1, 2)
|
||||
```
|
||||
|
||||
Usamos dos `INSERT` consultas para crear dos partes de datos diferentes. Si insertamos los datos con una sola consulta, ClickHouse crea una parte de datos y nunca realizará ninguna fusión.
|
||||
|
||||
Obtener los datos:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM UAct
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ 1 │ 1 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 5 │ 146 │ -1 │ 1 │
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
```
|
||||
|
||||
¿Qué vemos aquí y dónde están las partes colapsadas?
|
||||
Creamos dos partes de datos usando dos `INSERT` consulta. El `SELECT` la consulta se realizó en dos subprocesos, y el resultado es un orden aleatorio de filas.
|
||||
No se produjo el colapso porque las partes de datos aún no se han fusionado. ClickHouse fusiona partes de datos en un punto desconocido en el tiempo que no podemos predecir.
|
||||
|
||||
Es por eso que necesitamos agregación:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
UserID,
|
||||
sum(PageViews * Sign) AS PageViews,
|
||||
sum(Duration * Sign) AS Duration,
|
||||
Version
|
||||
FROM UAct
|
||||
GROUP BY UserID, Version
|
||||
HAVING sum(Sign) > 0
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Version─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 2 │
|
||||
└─────────────────────┴───────────┴──────────┴─────────┘
|
||||
```
|
||||
|
||||
Si no necesitamos agregación y queremos forzar el colapso, podemos usar el `FINAL` modificador para el `FROM` clausula.
|
||||
|
||||
``` sql
|
||||
SELECT * FROM UAct FINAL
|
||||
```
|
||||
|
||||
``` text
|
||||
┌──────────────UserID─┬─PageViews─┬─Duration─┬─Sign─┬─Version─┐
|
||||
│ 4324182021466249494 │ 6 │ 185 │ 1 │ 2 │
|
||||
└─────────────────────┴───────────┴──────────┴──────┴─────────┘
|
||||
```
|
||||
|
||||
Esta es una forma muy ineficiente de seleccionar datos. No lo use para mesas grandes.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/versionedcollapsingmergetree/) <!--hide-->
|
@ -1,71 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 45
|
||||
toc_title: "B\xFAfer"
|
||||
---
|
||||
|
||||
# Búfer {#buffer}
|
||||
|
||||
Almacena los datos para escribir en la memoria RAM, enjuagándolos periódicamente a otra tabla. Durante la operación de lectura, los datos se leen desde el búfer y la otra tabla simultáneamente.
|
||||
|
||||
``` sql
|
||||
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)
|
||||
```
|
||||
|
||||
Parámetros del motor:
|
||||
|
||||
- `database` – Database name. Instead of the database name, you can use a constant expression that returns a string.
|
||||
- `table` – Table to flush data to.
|
||||
- `num_layers` – Parallelism layer. Physically, the table will be represented as `num_layers` de búferes independientes. Valor recomendado: 16.
|
||||
- `min_time`, `max_time`, `min_rows`, `max_rows`, `min_bytes`, y `max_bytes` – Conditions for flushing data from the buffer.
|
||||
|
||||
Los datos se vacían del búfer y se escriben en la tabla de destino si `min*` condiciones o al menos una `max*` condición se cumplen.
|
||||
|
||||
- `min_time`, `max_time` – Condition for the time in seconds from the moment of the first write to the buffer.
|
||||
- `min_rows`, `max_rows` – Condition for the number of rows in the buffer.
|
||||
- `min_bytes`, `max_bytes` – Condition for the number of bytes in the buffer.
|
||||
|
||||
Durante la operación de escritura, los datos se insertan en un `num_layers` número de búferes aleatorios. O bien, si la parte de datos para insertar es lo suficientemente grande (mayor que `max_rows` o `max_bytes`), se escribe directamente en la tabla de destino, omitiendo el búfer.
|
||||
|
||||
Las condiciones para el lavado de los datos se calculan por separado para cada uno de los `num_layers` búfer. Por ejemplo, si `num_layers = 16` y `max_bytes = 100000000`, el consumo máximo de RAM es de 1.6 GB.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 16, 10, 100, 10000, 1000000, 10000000, 100000000)
|
||||
```
|
||||
|
||||
Creación de un ‘merge.hits_buffer’ mesa con la misma estructura que ‘merge.hits’ y usando el motor Buffer. Al escribir en esta tabla, los datos se almacenan en la memoria RAM y ‘merge.hits’ tabla. Se crean 16 búferes. Los datos de cada uno de ellos se vacían si han pasado 100 segundos o se han escrito un millón de filas o se han escrito 100 MB de datos; o si simultáneamente han pasado 10 segundos y se han escrito 10.000 filas y 10 MB de datos. Por ejemplo, si solo se ha escrito una fila, después de 100 segundos se vaciará, pase lo que pase. Pero si se han escrito muchas filas, los datos se vaciarán antes.
|
||||
|
||||
Cuando se detiene el servidor, con DROP TABLE o DETACH TABLE, los datos del búfer también se vacían a la tabla de destino.
|
||||
|
||||
Puede establecer cadenas vacías entre comillas simples para la base de datos y el nombre de la tabla. Esto indica la ausencia de una tabla de destino. En este caso, cuando se alcanzan las condiciones de descarga de datos, el búfer simplemente se borra. Esto puede ser útil para mantener una ventana de datos en la memoria.
|
||||
|
||||
Al leer desde una tabla de búfer, los datos se procesan tanto desde el búfer como desde la tabla de destino (si hay uno).
|
||||
Tenga en cuenta que las tablas Buffer no admiten un índice. En otras palabras, los datos del búfer se analizan por completo, lo que puede ser lento para los búferes grandes. (Para los datos de una tabla subordinada, se utilizará el índice que admite.)
|
||||
|
||||
Si el conjunto de columnas de la tabla Buffer no coincide con el conjunto de columnas de una tabla subordinada, se inserta un subconjunto de columnas que existen en ambas tablas.
|
||||
|
||||
Si los tipos no coinciden con una de las columnas de la tabla Búfer y una tabla subordinada, se escribe un mensaje de error en el registro del servidor y se borra el búfer.
|
||||
Lo mismo sucede si la tabla subordinada no existe cuando se vacía el búfer.
|
||||
|
||||
Si necesita ejecutar ALTER para una tabla subordinada y la tabla de búfer, se recomienda eliminar primero la tabla de búfer, ejecutar ALTER para la tabla subordinada y, a continuación, crear la tabla de búfer de nuevo.
|
||||
|
||||
Si el servidor se reinicia de forma anormal, se pierden los datos del búfer.
|
||||
|
||||
FINAL y SAMPLE no funcionan correctamente para las tablas Buffer. Estas condiciones se pasan a la tabla de destino, pero no se utilizan para procesar datos en el búfer. Si se requieren estas características, recomendamos usar solo la tabla Buffer para escribir, mientras lee desde la tabla de destino.
|
||||
|
||||
Al agregar datos a un búfer, uno de los búferes está bloqueado. Esto provoca retrasos si se realiza una operación de lectura simultáneamente desde la tabla.
|
||||
|
||||
Los datos que se insertan en una tabla de búfer pueden terminar en la tabla subordinada en un orden diferente y en bloques diferentes. Debido a esto, una tabla Buffer es difícil de usar para escribir en un CollapsingMergeTree correctamente. Para evitar problemas, puede establecer ‘num_layers’ a 1.
|
||||
|
||||
Si se replica la tabla de destino, se pierden algunas características esperadas de las tablas replicadas al escribir en una tabla de búfer. Los cambios aleatorios en el orden de las filas y los tamaños de las partes de datos hacen que la desduplicación de datos deje de funcionar, lo que significa que no es posible tener un ‘exactly once’ escribir en tablas replicadas.
|
||||
|
||||
Debido a estas desventajas, solo podemos recomendar el uso de una tabla Buffer en casos raros.
|
||||
|
||||
Una tabla de búfer se usa cuando se reciben demasiados INSERT de un gran número de servidores durante una unidad de tiempo y los datos no se pueden almacenar en búfer antes de la inserción, lo que significa que los INSERT no pueden ejecutarse lo suficientemente rápido.
|
||||
|
||||
Tenga en cuenta que no tiene sentido insertar datos una fila a la vez, incluso para las tablas de búfer. Esto solo producirá una velocidad de unos pocos miles de filas por segundo, mientras que la inserción de bloques de datos más grandes puede producir más de un millón de filas por segundo (consulte la sección “Performance”).
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/buffer/) <!--hide-->
|
@ -1,97 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 35
|
||||
toc_title: Diccionario
|
||||
---
|
||||
|
||||
# Diccionario {#dictionary}
|
||||
|
||||
El `Dictionary` el motor muestra el [diccionario](../../../sql-reference/dictionaries/external-dictionaries/external-dicts.md) datos como una tabla ClickHouse.
|
||||
|
||||
Como ejemplo, considere un diccionario de `products` con la siguiente configuración:
|
||||
|
||||
``` xml
|
||||
<dictionaries>
|
||||
<dictionary>
|
||||
<name>products</name>
|
||||
<source>
|
||||
<odbc>
|
||||
<table>products</table>
|
||||
<connection_string>DSN=some-db-server</connection_string>
|
||||
</odbc>
|
||||
</source>
|
||||
<lifetime>
|
||||
<min>300</min>
|
||||
<max>360</max>
|
||||
</lifetime>
|
||||
<layout>
|
||||
<flat/>
|
||||
</layout>
|
||||
<structure>
|
||||
<id>
|
||||
<name>product_id</name>
|
||||
</id>
|
||||
<attribute>
|
||||
<name>title</name>
|
||||
<type>String</type>
|
||||
<null_value></null_value>
|
||||
</attribute>
|
||||
</structure>
|
||||
</dictionary>
|
||||
</dictionaries>
|
||||
```
|
||||
|
||||
Consultar los datos del diccionario:
|
||||
|
||||
``` sql
|
||||
SELECT
|
||||
name,
|
||||
type,
|
||||
key,
|
||||
attribute.names,
|
||||
attribute.types,
|
||||
bytes_allocated,
|
||||
element_count,
|
||||
source
|
||||
FROM system.dictionaries
|
||||
WHERE name = 'products'
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─name─────┬─type─┬─key────┬─attribute.names─┬─attribute.types─┬─bytes_allocated─┬─element_count─┬─source──────────┐
|
||||
│ products │ Flat │ UInt64 │ ['title'] │ ['String'] │ 23065376 │ 175032 │ ODBC: .products │
|
||||
└──────────┴──────┴────────┴─────────────────┴─────────────────┴─────────────────┴───────────────┴─────────────────┘
|
||||
```
|
||||
|
||||
Puede usar el [dictGet\*](../../../sql-reference/functions/ext-dict-functions.md#ext_dict_functions) función para obtener los datos del diccionario en este formato.
|
||||
|
||||
Esta vista no es útil cuando necesita obtener datos sin procesar o cuando `JOIN` operación. Para estos casos, puede usar el `Dictionary` motor, que muestra los datos del diccionario en una tabla.
|
||||
|
||||
Sintaxis:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE %table_name% (%fields%) engine = Dictionary(%dictionary_name%)`
|
||||
```
|
||||
|
||||
Ejemplo de uso:
|
||||
|
||||
``` sql
|
||||
create table products (product_id UInt64, title String) Engine = Dictionary(products);
|
||||
```
|
||||
|
||||
Ok
|
||||
|
||||
Echa un vistazo a lo que hay en la mesa.
|
||||
|
||||
``` sql
|
||||
select * from products limit 1;
|
||||
```
|
||||
|
||||
``` text
|
||||
┌────product_id─┬─title───────────┐
|
||||
│ 152689 │ Some item │
|
||||
└───────────────┴─────────────────┘
|
||||
```
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/dictionary/) <!--hide-->
|
@ -1,152 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 33
|
||||
toc_title: Distribuido
|
||||
---
|
||||
|
||||
# Distribuido {#distributed}
|
||||
|
||||
**Las tablas con motor distribuido no almacenan ningún dato por sí mismas**, pero permite el procesamiento de consultas distribuidas en varios servidores.
|
||||
La lectura se paralela automáticamente. Durante una lectura, se utilizan los índices de tabla en servidores remotos, si los hay.
|
||||
|
||||
El motor distribuido acepta parámetros:
|
||||
|
||||
- el nombre del clúster en el archivo de configuración del servidor
|
||||
|
||||
- el nombre de una base de datos remota
|
||||
|
||||
- el nombre de una tabla remota
|
||||
|
||||
- (opcionalmente) clave de fragmentación
|
||||
|
||||
- nombre de política (opcionalmente), se usará para almacenar archivos temporales para el envío asíncrono
|
||||
|
||||
Ver también:
|
||||
|
||||
- `insert_distributed_sync` configuración
|
||||
- [Método de codificación de datos:](../mergetree-family/mergetree.md#table_engine-mergetree-multiple-volumes) para los ejemplos
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` sql
|
||||
Distributed(logs, default, hits[, sharding_key[, policy_name]])
|
||||
```
|
||||
|
||||
Los datos se leerán desde todos los servidores ‘logs’ clúster, desde el valor predeterminado.tabla de éxitos ubicada en cada servidor del clúster.
|
||||
Los datos no solo se leen sino que se procesan parcialmente en los servidores remotos (en la medida en que esto sea posible).
|
||||
Por ejemplo, para una consulta con GROUP BY, los datos se agregarán en servidores remotos y los estados intermedios de las funciones agregadas se enviarán al servidor solicitante. Luego, los datos se agregarán más.
|
||||
|
||||
En lugar del nombre de la base de datos, puede usar una expresión constante que devuelva una cadena. Por ejemplo: currentDatabase().
|
||||
|
||||
logs – The cluster name in the server's config file.
|
||||
|
||||
Los clústeres se establecen así:
|
||||
|
||||
``` xml
|
||||
<remote_servers>
|
||||
<logs>
|
||||
<shard>
|
||||
<!-- Optional. Shard weight when writing data. Default: 1. -->
|
||||
<weight>1</weight>
|
||||
<!-- Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas). -->
|
||||
<internal_replication>false</internal_replication>
|
||||
<replica>
|
||||
<host>example01-01-1</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
<replica>
|
||||
<host>example01-01-2</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
</shard>
|
||||
<shard>
|
||||
<weight>2</weight>
|
||||
<internal_replication>false</internal_replication>
|
||||
<replica>
|
||||
<host>example01-02-1</host>
|
||||
<port>9000</port>
|
||||
</replica>
|
||||
<replica>
|
||||
<host>example01-02-2</host>
|
||||
<secure>1</secure>
|
||||
<port>9440</port>
|
||||
</replica>
|
||||
</shard>
|
||||
</logs>
|
||||
</remote_servers>
|
||||
```
|
||||
|
||||
Aquí se define un clúster con el nombre ‘logs’ que consta de dos fragmentos, cada uno de los cuales contiene dos réplicas.
|
||||
Los fragmentos se refieren a los servidores que contienen diferentes partes de los datos (para leer todos los datos, debe acceder a todos los fragmentos).
|
||||
Las réplicas están duplicando servidores (para leer todos los datos, puede acceder a los datos en cualquiera de las réplicas).
|
||||
|
||||
Los nombres de clúster no deben contener puntos.
|
||||
|
||||
Los parámetros `host`, `port`, y opcionalmente `user`, `password`, `secure`, `compression` se especifican para cada servidor:
|
||||
- `host` – The address of the remote server. You can use either the domain or the IPv4 or IPv6 address. If you specify the domain, the server makes a DNS request when it starts, and the result is stored as long as the server is running. If the DNS request fails, the server doesn't start. If you change the DNS record, restart the server.
|
||||
- `port` – The TCP port for messenger activity (‘tcp_port’ en la configuración, generalmente establecido en 9000). No lo confundas con http_port.
|
||||
- `user` – Name of the user for connecting to a remote server. Default value: default. This user must have access to connect to the specified server. Access is configured in the users.xml file. For more information, see the section [Derechos de acceso](../../../operations/access-rights.md).
|
||||
- `password` – The password for connecting to a remote server (not masked). Default value: empty string.
|
||||
- `secure` - Use ssl para la conexión, por lo general también debe definir `port` = 9440. El servidor debe escuchar en `<tcp_port_secure>9440</tcp_port_secure>` y tener certificados correctos.
|
||||
- `compression` - Utilice la compresión de datos. Valor predeterminado: true.
|
||||
|
||||
When specifying replicas, one of the available replicas will be selected for each of the shards when reading. You can configure the algorithm for load balancing (the preference for which replica to access) – see the [load_balancing](../../../operations/settings/settings.md#settings-load_balancing) configuración.
|
||||
Si no se establece la conexión con el servidor, habrá un intento de conectarse con un breve tiempo de espera. Si la conexión falla, se seleccionará la siguiente réplica, y así sucesivamente para todas las réplicas. Si el intento de conexión falló para todas las réplicas, el intento se repetirá de la misma manera, varias veces.
|
||||
Esto funciona a favor de la resiliencia, pero no proporciona una tolerancia completa a errores: un servidor remoto podría aceptar la conexión, pero podría no funcionar o funcionar mal.
|
||||
|
||||
Puede especificar solo uno de los fragmentos (en este caso, el procesamiento de consultas debe denominarse remoto, en lugar de distribuido) o hasta cualquier número de fragmentos. En cada fragmento, puede especificar entre una y cualquier número de réplicas. Puede especificar un número diferente de réplicas para cada fragmento.
|
||||
|
||||
Puede especificar tantos clústeres como desee en la configuración.
|
||||
|
||||
Para ver los clústeres, utilice el ‘system.clusters’ tabla.
|
||||
|
||||
El motor distribuido permite trabajar con un clúster como un servidor local. Sin embargo, el clúster es inextensible: debe escribir su configuración en el archivo de configuración del servidor (mejor aún, para todos los servidores del clúster).
|
||||
|
||||
The Distributed engine requires writing clusters to the config file. Clusters from the config file are updated on the fly, without restarting the server. If you need to send a query to an unknown set of shards and replicas each time, you don't need to create a Distributed table – use the ‘remote’ función de tabla en su lugar. Vea la sección [Funciones de tabla](../../../sql-reference/table-functions/index.md).
|
||||
|
||||
Hay dos métodos para escribir datos en un clúster:
|
||||
|
||||
Primero, puede definir a qué servidores escribir en qué datos y realizar la escritura directamente en cada fragmento. En otras palabras, realice INSERT en las tablas que la tabla distribuida “looks at”. Esta es la solución más flexible, ya que puede usar cualquier esquema de fragmentación, que podría ser no trivial debido a los requisitos del área temática. Esta es también la solución más óptima ya que los datos se pueden escribir en diferentes fragmentos de forma completamente independiente.
|
||||
|
||||
En segundo lugar, puede realizar INSERT en una tabla distribuida. En este caso, la tabla distribuirá los datos insertados a través de los propios servidores. Para escribir en una tabla distribuida, debe tener un conjunto de claves de fragmentación (el último parámetro). Además, si solo hay un fragmento, la operación de escritura funciona sin especificar la clave de fragmentación, ya que no significa nada en este caso.
|
||||
|
||||
Cada fragmento puede tener un peso definido en el archivo de configuración. Por defecto, el peso es igual a uno. Los datos se distribuyen entre fragmentos en la cantidad proporcional al peso del fragmento. Por ejemplo, si hay dos fragmentos y el primero tiene un peso de 9 mientras que el segundo tiene un peso de 10, el primero se enviará 9 / 19 partes de las filas, y el segundo se enviará 10 / 19.
|
||||
|
||||
Cada fragmento puede tener el ‘internal_replication’ parámetro definido en el archivo de configuración.
|
||||
|
||||
Si este parámetro se establece en ‘true’, la operación de escritura selecciona la primera réplica en buen estado y escribe datos en ella. Utilice esta alternativa si la tabla Distribuida “looks at” tablas replicadas. En otras palabras, si la tabla donde se escribirán los datos los replicará por sí misma.
|
||||
|
||||
Si se establece en ‘false’ (el valor predeterminado), los datos se escriben en todas las réplicas. En esencia, esto significa que la tabla distribuida replica los datos en sí. Esto es peor que usar tablas replicadas, porque no se verifica la consistencia de las réplicas y, con el tiempo, contendrán datos ligeramente diferentes.
|
||||
|
||||
Para seleccionar el fragmento al que se envía una fila de datos, se analiza la expresión de fragmentación y su resto se toma de dividirlo por el peso total de los fragmentos. La fila se envía al fragmento que corresponde al medio intervalo de los restos de ‘prev_weight’ a ‘prev_weights + weight’, donde ‘prev_weights’ es el peso total de los fragmentos con el número más pequeño, y ‘weight’ es el peso de este fragmento. Por ejemplo, si hay dos fragmentos, y el primero tiene un peso de 9 mientras que el segundo tiene un peso de 10, la fila se enviará al primer fragmento para los restos del rango \[0, 9), y al segundo para los restos del rango \[9, 19).
|
||||
|
||||
La expresión de fragmentación puede ser cualquier expresión de constantes y columnas de tabla que devuelva un entero. Por ejemplo, puede usar la expresión ‘rand()’ para la distribución aleatoria de datos, o ‘UserID’ para la distribución por el resto de dividir la ID del usuario (entonces los datos de un solo usuario residirán en un solo fragmento, lo que simplifica la ejecución de IN y JOIN por los usuarios). Si una de las columnas no se distribuye lo suficientemente uniformemente, puede envolverla en una función hash: intHash64(UserID) .
|
||||
|
||||
Un simple recordatorio de la división es una solución limitada para sharding y no siempre es apropiado. Funciona para volúmenes medianos y grandes de datos (docenas de servidores), pero no para volúmenes muy grandes de datos (cientos de servidores o más). En este último caso, use el esquema de fragmentación requerido por el área asunto, en lugar de usar entradas en Tablas distribuidas.
|
||||
|
||||
SELECT queries are sent to all the shards and work regardless of how data is distributed across the shards (they can be distributed completely randomly). When you add a new shard, you don't have to transfer the old data to it. You can write new data with a heavier weight – the data will be distributed slightly unevenly, but queries will work correctly and efficiently.
|
||||
|
||||
Debería preocuparse por el esquema de fragmentación en los siguientes casos:
|
||||
|
||||
- Se utilizan consultas que requieren unir datos (IN o JOIN) mediante una clave específica. Si esta clave fragmenta datos, puede usar IN local o JOIN en lugar de GLOBAL IN o GLOBAL JOIN, que es mucho más eficiente.
|
||||
- Se usa una gran cantidad de servidores (cientos o más) con una gran cantidad de consultas pequeñas (consultas de clientes individuales: sitios web, anunciantes o socios). Para que las pequeñas consultas no afecten a todo el clúster, tiene sentido ubicar datos para un solo cliente en un solo fragmento. Alternativamente, como lo hemos hecho en Yandex.Metrica, puede configurar sharding de dos niveles: divida todo el clúster en “layers”, donde una capa puede consistir en varios fragmentos. Los datos de un único cliente se encuentran en una sola capa, pero los fragmentos se pueden agregar a una capa según sea necesario y los datos se distribuyen aleatoriamente dentro de ellos. Las tablas distribuidas se crean para cada capa y se crea una única tabla distribuida compartida para consultas globales.
|
||||
|
||||
Los datos se escriben de forma asíncrona. Cuando se inserta en la tabla, el bloque de datos se acaba de escribir en el sistema de archivos local. Los datos se envían a los servidores remotos en segundo plano tan pronto como sea posible. El período de envío de datos está gestionado por el [Distributed_directory_monitor_sleep_time_ms](../../../operations/settings/settings.md#distributed_directory_monitor_sleep_time_ms) y [Distributed_directory_monitor_max_sleep_time_ms](../../../operations/settings/settings.md#distributed_directory_monitor_max_sleep_time_ms) configuración. El `Distributed` el motor envía cada archivo con datos insertados por separado, pero puede habilitar el envío por lotes de archivos [distributed_directory_monitor_batch_inserts](../../../operations/settings/settings.md#distributed_directory_monitor_batch_inserts) configuración. Esta configuración mejora el rendimiento del clúster al utilizar mejor los recursos de red y servidor local. Debe comprobar si los datos se envían correctamente comprobando la lista de archivos (datos en espera de ser enviados) en el directorio de la tabla: `/var/lib/clickhouse/data/database/table/`.
|
||||
|
||||
Si el servidor dejó de existir o tuvo un reinicio aproximado (por ejemplo, después de un error de dispositivo) después de un INSERT en una tabla distribuida, es posible que se pierdan los datos insertados. Si se detecta un elemento de datos dañado en el directorio de la tabla, se transfiere al ‘broken’ subdirectorio y ya no se utiliza.
|
||||
|
||||
Cuando la opción max_parallel_replicas está habilitada, el procesamiento de consultas se paralela en todas las réplicas dentro de un solo fragmento. Para obtener más información, consulte la sección [max_parallel_replicas](../../../operations/settings/settings.md#settings-max_parallel_replicas).
|
||||
|
||||
## Virtual Columnas {#virtual-columns}
|
||||
|
||||
- `_shard_num` — Contains the `shard_num` (de `system.clusters`). Tipo: [UInt32](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
!!! note "Nota"
|
||||
Ya [`remote`](../../../sql-reference/table-functions/remote.md)/`cluster` funciones de tabla crean internamente instancia temporal del mismo motor distribuido, `_shard_num` está disponible allí también.
|
||||
|
||||
**Ver también**
|
||||
|
||||
- [Virtual columnas](index.md#table_engines-virtual_columns)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/distributed/) <!--hide-->
|
@ -1,68 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 34
|
||||
toc_title: Datos externos
|
||||
---
|
||||
|
||||
# Datos externos para el procesamiento de consultas {#external-data-for-query-processing}
|
||||
|
||||
ClickHouse permite enviar a un servidor los datos necesarios para procesar una consulta, junto con una consulta SELECT. Estos datos se colocan en una tabla temporal (consulte la sección “Temporary tables”) y se puede utilizar en la consulta (por ejemplo, en operadores IN).
|
||||
|
||||
Por ejemplo, si tiene un archivo de texto con identificadores de usuario importantes, puede cargarlo en el servidor junto con una consulta que utilice la filtración de esta lista.
|
||||
|
||||
Si necesita ejecutar más de una consulta con un gran volumen de datos externos, no utilice esta función. Es mejor cargar los datos a la base de datos con anticipación.
|
||||
|
||||
Los datos externos se pueden cargar mediante el cliente de línea de comandos (en modo no interactivo) o mediante la interfaz HTTP.
|
||||
|
||||
En el cliente de línea de comandos, puede especificar una sección de parámetros en el formato
|
||||
|
||||
``` bash
|
||||
--external --file=... [--name=...] [--format=...] [--types=...|--structure=...]
|
||||
```
|
||||
|
||||
Puede tener varias secciones como esta, para el número de tablas que se transmiten.
|
||||
|
||||
**–external** – Marks the beginning of a clause.
|
||||
**–file** – Path to the file with the table dump, or -, which refers to stdin.
|
||||
Solo se puede recuperar una sola tabla de stdin.
|
||||
|
||||
Los siguientes parámetros son opcionales: **–name**– Name of the table. If omitted, _data is used.
|
||||
**–format** – Data format in the file. If omitted, TabSeparated is used.
|
||||
|
||||
Se requiere uno de los siguientes parámetros:**–types** – A list of comma-separated column types. For example: `UInt64,String`. The columns will be named _1, _2, …
|
||||
**–structure**– The table structure in the format`UserID UInt64`, `URL String`. Define los nombres y tipos de columna.
|
||||
|
||||
Los archivos especificados en ‘file’ se analizará mediante el formato especificado en ‘format’ utilizando los tipos de datos especificados en ‘types’ o ‘structure’. La mesa será cargado en el servidor y accesibles, como una tabla temporal con el nombre de ‘name’.
|
||||
|
||||
Ejemplos:
|
||||
|
||||
``` bash
|
||||
$ echo -ne "1\n2\n3\n" | clickhouse-client --query="SELECT count() FROM test.visits WHERE TraficSourceID IN _data" --external --file=- --types=Int8
|
||||
849897
|
||||
$ cat /etc/passwd | sed 's/:/\t/g' | clickhouse-client --query="SELECT shell, count() AS c FROM passwd GROUP BY shell ORDER BY c DESC" --external --file=- --name=passwd --structure='login String, unused String, uid UInt16, gid UInt16, comment String, home String, shell String'
|
||||
/bin/sh 20
|
||||
/bin/false 5
|
||||
/bin/bash 4
|
||||
/usr/sbin/nologin 1
|
||||
/bin/sync 1
|
||||
```
|
||||
|
||||
Cuando se utiliza la interfaz HTTP, los datos externos se pasan en el formato multipart/form-data. Cada tabla se transmite como un archivo separado. El nombre de la tabla se toma del nombre del archivo. El ‘query_string’ se pasa los parámetros ‘name_format’, ‘name_types’, y ‘name_structure’, donde ‘name’ es el nombre de la tabla a la que corresponden estos parámetros. El significado de los parámetros es el mismo que cuando se usa el cliente de línea de comandos.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` bash
|
||||
$ cat /etc/passwd | sed 's/:/\t/g' > passwd.tsv
|
||||
|
||||
$ curl -F 'passwd=@passwd.tsv;' 'http://localhost:8123/?query=SELECT+shell,+count()+AS+c+FROM+passwd+GROUP+BY+shell+ORDER+BY+c+DESC&passwd_structure=login+String,+unused+String,+uid+UInt16,+gid+UInt16,+comment+String,+home+String,+shell+String'
|
||||
/bin/sh 20
|
||||
/bin/false 5
|
||||
/bin/bash 4
|
||||
/usr/sbin/nologin 1
|
||||
/bin/sync 1
|
||||
```
|
||||
|
||||
Para el procesamiento de consultas distribuidas, las tablas temporales se envían a todos los servidores remotos.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/external_data/) <!--hide-->
|
@ -1,90 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 37
|
||||
toc_title: File
|
||||
---
|
||||
|
||||
# File {#table_engines-file}
|
||||
|
||||
El motor de tabla de archivos mantiene los datos en un archivo en uno de los [file
|
||||
formato](../../../interfaces/formats.md#formats) (TabSeparated, Native, etc.).
|
||||
|
||||
Ejemplos de uso:
|
||||
|
||||
- Exportación de datos de ClickHouse a archivo.
|
||||
- Convertir datos de un formato a otro.
|
||||
- Actualización de datos en ClickHouse mediante la edición de un archivo en un disco.
|
||||
|
||||
## Uso en el servidor ClickHouse {#usage-in-clickhouse-server}
|
||||
|
||||
``` sql
|
||||
File(Format)
|
||||
```
|
||||
|
||||
El `Format` parámetro especifica uno de los formatos de archivo disponibles. Realizar
|
||||
`SELECT` consultas, el formato debe ser compatible para la entrada, y para realizar
|
||||
`INSERT` queries – for output. The available formats are listed in the
|
||||
[Formato](../../../interfaces/formats.md#formats) apartado.
|
||||
|
||||
ClickHouse no permite especificar la ruta del sistema de archivos para`File`. Utilizará la carpeta definida por [camino](../../../operations/server-configuration-parameters/settings.md) configuración en la configuración del servidor.
|
||||
|
||||
Al crear una tabla usando `File(Format)` crea un subdirectorio vacío en esa carpeta. Cuando los datos se escriben en esa tabla, se colocan en `data.Format` en ese subdirectorio.
|
||||
|
||||
Puede crear manualmente esta subcarpeta y archivo en el sistema de archivos del servidor y luego [ATTACH](../../../sql-reference/statements/misc.md) para mostrar información con el nombre coincidente, para que pueda consultar datos desde ese archivo.
|
||||
|
||||
!!! warning "Advertencia"
|
||||
Tenga cuidado con esta funcionalidad, ya que ClickHouse no realiza un seguimiento de los cambios externos en dichos archivos. El resultado de las escrituras simultáneas a través de ClickHouse y fuera de ClickHouse no está definido.
|
||||
|
||||
**Ejemplo:**
|
||||
|
||||
**1.** Configurar el `file_engine_table` tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE file_engine_table (name String, value UInt32) ENGINE=File(TabSeparated)
|
||||
```
|
||||
|
||||
Por defecto, ClickHouse creará una carpeta `/var/lib/clickhouse/data/default/file_engine_table`.
|
||||
|
||||
**2.** Crear manualmente `/var/lib/clickhouse/data/default/file_engine_table/data.TabSeparated` contener:
|
||||
|
||||
``` bash
|
||||
$ cat data.TabSeparated
|
||||
one 1
|
||||
two 2
|
||||
```
|
||||
|
||||
**3.** Consultar los datos:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM file_engine_table
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─name─┬─value─┐
|
||||
│ one │ 1 │
|
||||
│ two │ 2 │
|
||||
└──────┴───────┘
|
||||
```
|
||||
|
||||
## Uso en ClickHouse-local {#usage-in-clickhouse-local}
|
||||
|
||||
En [Sistema abierto.](../../../operations/utilities/clickhouse-local.md#clickhouse-local) El motor de archivos acepta la ruta del archivo además de `Format`. Los flujos de entrada / salida predeterminados se pueden especificar utilizando nombres numéricos o legibles por humanos como `0` o `stdin`, `1` o `stdout`.
|
||||
**Ejemplo:**
|
||||
|
||||
``` bash
|
||||
$ echo -e "1,2\n3,4" | clickhouse-local -q "CREATE TABLE table (a Int64, b Int64) ENGINE = File(CSV, stdin); SELECT a, b FROM table; DROP TABLE table"
|
||||
```
|
||||
|
||||
## Detalles de la implementación {#details-of-implementation}
|
||||
|
||||
- Multiple `SELECT` las consultas se pueden realizar simultáneamente, pero `INSERT` las consultas se esperarán entre sí.
|
||||
- Apoyado la creación de nuevos archivos por `INSERT` consulta.
|
||||
- Si el archivo existe, `INSERT` añadiría nuevos valores en él.
|
||||
- No soportado:
|
||||
- `ALTER`
|
||||
- `SELECT ... SAMPLE`
|
||||
- Indice
|
||||
- Replicación
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/file/) <!--hide-->
|
@ -1,61 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 46
|
||||
toc_title: GenerateRandom
|
||||
---
|
||||
|
||||
# Generaterandom {#table_engines-generate}
|
||||
|
||||
El motor de tabla GenerateRandom produce datos aleatorios para el esquema de tabla determinado.
|
||||
|
||||
Ejemplos de uso:
|
||||
|
||||
- Se usa en la prueba para poblar una tabla grande reproducible.
|
||||
- Generar entrada aleatoria para pruebas de fuzzing.
|
||||
|
||||
## Uso en el servidor ClickHouse {#usage-in-clickhouse-server}
|
||||
|
||||
``` sql
|
||||
ENGINE = GenerateRandom(random_seed, max_string_length, max_array_length)
|
||||
```
|
||||
|
||||
El `max_array_length` y `max_string_length` parámetros especifican la longitud máxima de todos
|
||||
columnas y cadenas de matriz correspondientemente en los datos generados.
|
||||
|
||||
Generar motor de tabla sólo admite `SELECT` consulta.
|
||||
|
||||
Es compatible con todos [Tipos de datos](../../../sql-reference/data-types/index.md) que se pueden almacenar en una tabla excepto `LowCardinality` y `AggregateFunction`.
|
||||
|
||||
**Ejemplo:**
|
||||
|
||||
**1.** Configurar el `generate_engine_table` tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE generate_engine_table (name String, value UInt32) ENGINE = GenerateRandom(1, 5, 3)
|
||||
```
|
||||
|
||||
**2.** Consultar los datos:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM generate_engine_table LIMIT 3
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─name─┬──────value─┐
|
||||
│ c4xJ │ 1412771199 │
|
||||
│ r │ 1791099446 │
|
||||
│ 7#$ │ 124312908 │
|
||||
└──────┴────────────┘
|
||||
```
|
||||
|
||||
## Detalles de la implementación {#details-of-implementation}
|
||||
|
||||
- No soportado:
|
||||
- `ALTER`
|
||||
- `SELECT ... SAMPLE`
|
||||
- `INSERT`
|
||||
- Indice
|
||||
- Replicación
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/generate/) <!--hide-->
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_folder_title: Especial
|
||||
toc_priority: 31
|
||||
---
|
||||
|
||||
|
@ -1,111 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 40
|
||||
toc_title: Unir
|
||||
---
|
||||
|
||||
# Unir {#join}
|
||||
|
||||
Estructura de datos preparada para usar en [JOIN](../../../sql-reference/statements/select/join.md#select-join) operación.
|
||||
|
||||
## Creación de una tabla {#creating-a-table}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
|
||||
(
|
||||
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
|
||||
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
|
||||
) ENGINE = Join(join_strictness, join_type, k1[, k2, ...])
|
||||
```
|
||||
|
||||
Vea la descripción detallada del [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query) consulta.
|
||||
|
||||
**Parámetros del motor**
|
||||
|
||||
- `join_strictness` – [ÚNETE a la rigurosidad](../../../sql-reference/statements/select/join.md#select-join-types).
|
||||
- `join_type` – [Tipo de unión](../../../sql-reference/statements/select/join.md#select-join-types).
|
||||
- `k1[, k2, ...]` – Key columns from the `USING` cláusula que el `JOIN` operación se hace con.
|
||||
|
||||
Entrar `join_strictness` y `join_type` parámetros sin comillas, por ejemplo, `Join(ANY, LEFT, col1)`. Deben coincidir con el `JOIN` operación para la que se utilizará la tabla. Si los parámetros no coinciden, ClickHouse no lanza una excepción y puede devolver datos incorrectos.
|
||||
|
||||
## Uso de la tabla {#table-usage}
|
||||
|
||||
### Ejemplo {#example}
|
||||
|
||||
Creación de la tabla del lado izquierdo:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE id_val(`id` UInt32, `val` UInt32) ENGINE = TinyLog
|
||||
```
|
||||
|
||||
``` sql
|
||||
INSERT INTO id_val VALUES (1,11)(2,12)(3,13)
|
||||
```
|
||||
|
||||
Creando el lado derecho `Join` tabla:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE id_val_join(`id` UInt32, `val` UInt8) ENGINE = Join(ANY, LEFT, id)
|
||||
```
|
||||
|
||||
``` sql
|
||||
INSERT INTO id_val_join VALUES (1,21)(1,22)(3,23)
|
||||
```
|
||||
|
||||
Unirse a las tablas:
|
||||
|
||||
``` sql
|
||||
SELECT * FROM id_val ANY LEFT JOIN id_val_join USING (id) SETTINGS join_use_nulls = 1
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─id─┬─val─┬─id_val_join.val─┐
|
||||
│ 1 │ 11 │ 21 │
|
||||
│ 2 │ 12 │ ᴺᵁᴸᴸ │
|
||||
│ 3 │ 13 │ 23 │
|
||||
└────┴─────┴─────────────────┘
|
||||
```
|
||||
|
||||
Como alternativa, puede recuperar datos del `Join` tabla, especificando el valor de la clave de unión:
|
||||
|
||||
``` sql
|
||||
SELECT joinGet('id_val_join', 'val', toUInt32(1))
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─joinGet('id_val_join', 'val', toUInt32(1))─┐
|
||||
│ 21 │
|
||||
└────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Selección e inserción de datos {#selecting-and-inserting-data}
|
||||
|
||||
Usted puede utilizar `INSERT` consultas para agregar datos al `Join`-mesas de motor. Si la tabla se creó con el `ANY` estricta, se ignoran los datos de las claves duplicadas. Con el `ALL` estricta, se agregan todas las filas.
|
||||
|
||||
No se puede realizar una `SELECT` consulta directamente desde la tabla. En su lugar, use uno de los siguientes métodos:
|
||||
|
||||
- Coloque la mesa hacia el lado derecho en un `JOIN` clausula.
|
||||
- Llame al [joinGet](../../../sql-reference/functions/other-functions.md#joinget) función, que le permite extraer datos de la tabla de la misma manera que de un diccionario.
|
||||
|
||||
### Limitaciones y ajustes {#join-limitations-and-settings}
|
||||
|
||||
Al crear una tabla, se aplican los siguientes valores:
|
||||
|
||||
- [Sistema abierto.](../../../operations/settings/settings.md#join_use_nulls)
|
||||
- [Método de codificación de datos:](../../../operations/settings/query-complexity.md#settings-max_rows_in_join)
|
||||
- [Método de codificación de datos:](../../../operations/settings/query-complexity.md#settings-max_bytes_in_join)
|
||||
- [join_overflow_mode](../../../operations/settings/query-complexity.md#settings-join_overflow_mode)
|
||||
- [join_any_take_last_row](../../../operations/settings/settings.md#settings-join_any_take_last_row)
|
||||
|
||||
El `Join`-las tablas del motor no se pueden usar en `GLOBAL JOIN` operación.
|
||||
|
||||
El `Join`-motor permite el uso [Sistema abierto.](../../../operations/settings/settings.md#join_use_nulls) ajuste en el `CREATE TABLE` instrucción. Y [SELECT](../../../sql-reference/statements/select/index.md) consulta permite el uso `join_use_nulls` demasiado. Si tienes diferentes `join_use_nulls` configuración, puede obtener un error al unirse a la tabla. Depende del tipo de JOIN. Cuando se utiliza [joinGet](../../../sql-reference/functions/other-functions.md#joinget) función, usted tiene que utilizar el mismo `join_use_nulls` ajuste en `CRATE TABLE` y `SELECT` instrucción.
|
||||
|
||||
## Almacenamiento de datos {#data-storage}
|
||||
|
||||
`Join` datos de la tabla siempre se encuentra en la memoria RAM. Al insertar filas en una tabla, ClickHouse escribe bloques de datos en el directorio del disco para que puedan restaurarse cuando se reinicie el servidor.
|
||||
|
||||
Si el servidor se reinicia incorrectamente, el bloque de datos en el disco puede perderse o dañarse. En este caso, es posible que deba eliminar manualmente el archivo con datos dañados.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/join/) <!--hide-->
|
@ -1,12 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 43
|
||||
toc_title: "M\xE9todo de codificaci\xF3n de datos:"
|
||||
---
|
||||
|
||||
# Método de codificación de datos: {#materializedview}
|
||||
|
||||
Se utiliza para implementar vistas materializadas (para obtener más información, consulte [CREATE TABLE](../../../sql-reference/statements/create.md#create-table-query)). Para almacenar datos, utiliza un motor diferente que se especificó al crear la vista. Al leer desde una tabla, solo usa este motor.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/materializedview/) <!--hide-->
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 44
|
||||
toc_title: Memoria
|
||||
---
|
||||
|
||||
# Memoria {#memory}
|
||||
|
||||
El motor de memoria almacena datos en RAM, en forma sin comprimir. Los datos se almacenan exactamente en la misma forma en que se reciben cuando se leen. En otras palabras, la lectura de esta tabla es completamente gratuita.
|
||||
El acceso a los datos simultáneos está sincronizado. Los bloqueos son cortos: las operaciones de lectura y escritura no se bloquean entre sí.
|
||||
Los índices no son compatibles. La lectura está paralelizada.
|
||||
La productividad máxima (más de 10 GB/s) se alcanza en consultas simples, porque no hay lectura del disco, descomprimir o deserializar datos. (Cabe señalar que, en muchos casos, la productividad del motor MergeTree es casi tan alta.)
|
||||
Al reiniciar un servidor, los datos desaparecen de la tabla y la tabla queda vacía.
|
||||
Normalmente, el uso de este motor de tabla no está justificado. Sin embargo, se puede usar para pruebas y para tareas donde se requiere la velocidad máxima en un número relativamente pequeño de filas (hasta aproximadamente 100,000,000).
|
||||
|
||||
El sistema utiliza el motor de memoria para tablas temporales con datos de consulta externos (consulte la sección “External data for processing a query”), y para la implementación de GLOBAL IN (véase la sección “IN operators”).
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/memory/) <!--hide-->
|
@ -1,70 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 36
|
||||
toc_title: Fusionar
|
||||
---
|
||||
|
||||
# Fusionar {#merge}
|
||||
|
||||
El `Merge` motor (no debe confundirse con `MergeTree`) no almacena datos en sí, pero permite leer de cualquier número de otras tablas simultáneamente.
|
||||
La lectura se paralela automáticamente. No se admite la escritura en una tabla. Al leer, se usan los índices de las tablas que realmente se están leyendo, si existen.
|
||||
El `Merge` engine acepta parámetros: el nombre de la base de datos y una expresión regular para las tablas.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
``` sql
|
||||
Merge(hits, '^WatchLog')
|
||||
```
|
||||
|
||||
Los datos se leerán de las tablas en el `hits` base de datos que tienen nombres que coinciden con la expresión regular ‘`^WatchLog`’.
|
||||
|
||||
En lugar del nombre de la base de datos, puede usar una expresión constante que devuelva una cadena. Por ejemplo, `currentDatabase()`.
|
||||
|
||||
Regular expressions — [Re2](https://github.com/google/re2) (soporta un subconjunto de PCRE), sensible a mayúsculas y minúsculas.
|
||||
Vea las notas sobre los símbolos de escape en expresiones regulares en el “match” apartado.
|
||||
|
||||
Al seleccionar tablas para leer, el `Merge` no se seleccionará la tabla en sí, incluso si coincide con la expresión regular. Esto es para evitar bucles.
|
||||
Es posible crear dos `Merge` tablas que intentarán interminablemente leer los datos de los demás, pero esta no es una buena idea.
|
||||
|
||||
La forma típica de usar el `Merge` para trabajar con un gran número de `TinyLog` tablas como si con una sola tabla.
|
||||
|
||||
Ejemplo 2:
|
||||
|
||||
Digamos que tiene una tabla antigua (WatchLog_old) y decidió cambiar la partición sin mover datos a una nueva tabla (WatchLog_new) y necesita ver datos de ambas tablas.
|
||||
|
||||
``` sql
|
||||
CREATE TABLE WatchLog_old(date Date, UserId Int64, EventType String, Cnt UInt64)
|
||||
ENGINE=MergeTree(date, (UserId, EventType), 8192);
|
||||
INSERT INTO WatchLog_old VALUES ('2018-01-01', 1, 'hit', 3);
|
||||
|
||||
CREATE TABLE WatchLog_new(date Date, UserId Int64, EventType String, Cnt UInt64)
|
||||
ENGINE=MergeTree PARTITION BY date ORDER BY (UserId, EventType) SETTINGS index_granularity=8192;
|
||||
INSERT INTO WatchLog_new VALUES ('2018-01-02', 2, 'hit', 3);
|
||||
|
||||
CREATE TABLE WatchLog as WatchLog_old ENGINE=Merge(currentDatabase(), '^WatchLog');
|
||||
|
||||
SELECT *
|
||||
FROM WatchLog
|
||||
```
|
||||
|
||||
``` text
|
||||
┌───────date─┬─UserId─┬─EventType─┬─Cnt─┐
|
||||
│ 2018-01-01 │ 1 │ hit │ 3 │
|
||||
└────────────┴────────┴───────────┴─────┘
|
||||
┌───────date─┬─UserId─┬─EventType─┬─Cnt─┐
|
||||
│ 2018-01-02 │ 2 │ hit │ 3 │
|
||||
└────────────┴────────┴───────────┴─────┘
|
||||
```
|
||||
|
||||
## Virtual Columnas {#virtual-columns}
|
||||
|
||||
- `_table` — Contains the name of the table from which data was read. Type: [Cadena](../../../sql-reference/data-types/string.md).
|
||||
|
||||
Puede establecer las condiciones constantes en `_table` en el `WHERE/PREWHERE` cláusula (por ejemplo, `WHERE _table='xyz'`). En este caso, la operación de lectura se realiza sólo para las tablas donde la condición en `_table` está satisfecho, por lo que el `_table` columna actúa como un índice.
|
||||
|
||||
**Ver también**
|
||||
|
||||
- [Virtual columnas](index.md#table_engines-virtual_columns)
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/merge/) <!--hide-->
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
machine_translated: true
|
||||
machine_translated_rev: 72537a2d527c63c07aa5d2361a8829f3895cf2bd
|
||||
toc_priority: 38
|
||||
toc_title: Nulo
|
||||
---
|
||||
|
||||
# Nulo {#null}
|
||||
|
||||
Al escribir en una tabla Null, los datos se ignoran. Al leer desde una tabla Null, la respuesta está vacía.
|
||||
|
||||
Sin embargo, puede crear una vista materializada en una tabla Null. Entonces los datos escritos en la tabla terminarán en la vista.
|
||||
|
||||
[Artículo Original](https://clickhouse.tech/docs/en/operations/table_engines/null/) <!--hide-->
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user