CREATE TABLE hits
(
URL String,
Domain String,
CONSTRAINT c_valid_url CHECK isValidUTF8(URL),
CONSTRAINT c_domain CHECK Domain = domain(URL)
)
Данные проверяются при INSERT.
Разработчик — Глеб Новиков, ВШЭ
INSERT INTO hits VALUES ('https://yandex.ru/', 'google.com')
Exception: Constraint `c_domain` for table `hits`
is violated at row 1.
Expression: (Domain = domain(URL)).
Column values:
URL = 'https://yandex.ru/',
Domain = 'google.com'.
Не проверяются при фоновых мержах.
Не проверяются при ALTER UPDATE.
ALTER TABLE hits ADD CONSTRAINT
c_valid_url CHECK isValidUTF8(URL)
При добавлении CONSTRAINT, старые данные не проверяются.
ALTER TABLE hits DROP CONSTRAINT c_valid_url
SELECT count()
FROM test.hits
WHERE CounterID = {id:UInt32}
AND SearchPhrase = {phrase:String}
— подстановки именованные и типизированные;
— подставляются на уровне синтаксического дерева.
TODO:
— подстановки для множеств в секции IN;
— подстановки для имён таблиц, столбцов, баз данных.
— возможность задать URL с предустановленными запросами.
Разработчик — Александр Третьяков, ВШЭ
$ curl "http://localhost:8123/" --data-binary \
"SELECT count() FROM test.hits WHERE CounterID = {id:UInt32}"
Exception: Query parameter `id` was not set.
$ curl "http://localhost:8123/?param_id=34" --data-binary \
"SELECT count() FROM test.hits WHERE CounterID = {id:UInt32}"
1962
$ curl "http://localhost:8123/?param_id=34;%20DROP%20DATABASE%20test" ...
"SELECT count() FROM test.hits WHERE CounterID = {id:UInt32}"
Exception: Value 34; DROP DATABASE test
cannot be parsed as UInt32 for query parameter 'id'
$ curl "http://localhost:8123/?param_id=34;%20DROP%20DATABASE%20test" ...
"SELECT count() FROM test.hits WHERE CounterID = {id:String}"
Exception: Illegal types of arguments (UInt32, String) of function equals
— Protobuf;
— Parquet;
— ORC (input-only) — ArenaData;
— Template, TemplateIgnoreSpaces;
Позволяет задать шаблон для форматирования или парсинга данных.
Шаблон содержит разделители и подстановки.
Для подстановок указан способ экранирования значений:
Quoted, Escaped, CSV, JSON, XML, Raw.
Website ${domain:Quoted} has ${count:Raw} pageviews.
Задаётся шаблон для строк, разделитель между строками
и шаблон для resultset.
Пример: распарсить access логи.
Пример: распарсить сложный вложенный JSON.
Пример: сформировать HTML прямо из ClickHouse.
с использованием ключа сортировки таблицы
SELECT event_time, message
FROM system.text_log
ORDER BY event_date DESC, event_time DESC
LIMIT 10
┌──────────event_time─┬─message───────────────────────────────────────────┐
│ 2019-09-05 04:20:35 │ Renaming temporary part tmp_insert_201909_10_10_0 │
│ 2019-09-05 04:20:35 │ Flushing system log │
│ 2019-09-05 04:20:34 │ Flushing system log │
│ 2019-09-05 04:20:34 │ Renaming temporary part tmp_insert_201909_10_10_0 │
│ 2019-09-05 04:20:28 │ Renaming temporary part tmp_insert_201909_9_9_0 to│
│ 2019-09-05 04:20:28 │ Flushing system log │
│ 2019-09-05 04:20:27 │ Renaming temporary part tmp_insert_201909_9_9_0 to│
...
└─────────────────────┴───────────────────────────────────────────────────┘
10 rows in set. Elapsed: 0.291 sec. Processed 42.21 million rows, 6.10 GB
(145.13 million rows/s., 20.98 GB/s.)
с использованием ключа сортировки таблицы
:) SET optimize_read_in_order = 1
:) SELECT event_time, message
FROM system.text_log
ORDER BY event_date DESC, event_time DESC
LIMIT 10
┌──────────event_time─┬─message───────────────────────────────────────────┐
│ 2019-09-05 04:28:59 │ Merged 6 parts: from 201909_1_96_19 to 201909_101_│
│ 2019-09-05 04:28:59 │ Renaming temporary part tmp_merge_201909_1_101_20 │
│ 2019-09-05 04:28:59 │ Merge sorted 761 rows, containing 202 columns (202│
│ 2019-09-05 04:28:59 │ Reading 2 marks from part 201909_101_101_0, total │
│ 2019-09-05 04:28:59 │ Reading 2 marks from part 201909_100_100_0, total │
...
└─────────────────────┴───────────────────────────────────────────────────┘
10 rows in set. Elapsed: 0.012 sec. Processed 54.41 thousand rows, 7.42 MB
(4.68 million rows/s., 637.76 MB/s.)
с использованием ключа сортировки таблицы
— ORDER BY по ключу сортировки;
— ASC / DESC / вперемешку:
ORDER BY event_date DESC, event_time ASC
— или его префиксу:
ORDER BY event_date DESC
— или по выражениям с монотонными функциями от него;
ORDER BY event_date DESC, -toUInt32(event_time)
— доступно с версии 19.14;
Разработчик — Антон Попов, Яндекс; Анастасия Родигина, ВШЭ
SELECT EventDate, count() FROM table
GROUP BY EventDate ORDER BY EventDate
┌──EventDate─┬─count()─┐
│ 2019-09-01 │ 5 │
│ 2019-09-02 │ 3 │
│ 2019-09-04 │ 4 │
│ 2019-09-05 │ 1 │
└────────────┴─────────┘
SELECT EventDate, count() FROM table
GROUP BY EventDate ORDER BY EventDate WITH FILL
┌──EventDate─┬─count()─┐
│ 2019-09-01 │ 5 │
│ 2019-09-02 │ 3 │
│ 2019-09-03 │ 0 │
│ 2019-09-04 │ 4 │
│ 2019-09-05 │ 1 │
└────────────┴─────────┘
WITH FILL — модификатор для элемента ORDER BY;
WITH FILL FROM start
WITH FILL FROM start TO end
WITH FILL FROM start TO end STEP step
WITH FILL может быть применён к каждому элементу ORDER BY:
ORDER BY EventDate WITH FILL, EventTime WITH FILL STEP 3600
— ещё даже не помержено.
Разработчик — Антон Попов, Яндекс; Дмитрий Уткин, ВШЭ
SELECT * FROM table
WHERE Passport = 7609164285
<query_masking_rules>
<rule>
<regexp>Passport = \d+</regexp>
<replace>Passport = ***</replace>
</rule>
<query_masking_rules>
— подавляет данные в логах и системных таблицах;
Разработчик — Михаил Филимонов, Altinity
в системных таблицах:
— system.query_log;
— system.query_thread_log;
— system.part_log;
— system.trace_log;
— system.text_log;
— system.metric_log;
system.text_log
Теперь мы пишем логи ClickHouse в ClickHouse!
DESCRIBE TABLE system.text_log
┌─name──────────┬─type───────────────────┐
│ event_date │ Date │
│ event_time │ DateTime │
│ microseconds │ UInt32 │
│ thread_name │ LowCardinality(String) │
│ thread_number │ UInt32 │
│ os_thread_id │ UInt32 │
│ level │ Enum8('Fatal' = 1, '...│
│ query_id │ String │
│ logger_name │ LowCardinality(String) │
│ message │ String │
│ revision │ UInt32 │
│ source_file │ LowCardinality(String) │
│ source_line │ UInt64 │
└───────────────┴────────────────────────┘
system.metric_log
— для тех, кто забыл настроить мониторинг.
— сохраняет все метрики ClickHouse раз в секунду (по-умолчанию).
SELECT
toStartOfMinute(event_time) AS h,
sum(ProfileEvent_UserTimeMicroseconds) AS user_time,
bar(user_time, 0, 60000000, 80) AS bar
FROM system.metric_log WHERE event_date = today()
GROUP BY h ORDER BY h
SELECT
toStartOfMinute(event_time) AS h,
sum(ProfileEvent_UserTimeMicroseconds) AS user_time,
bar(user_time, 0, 60000000, 80) AS bar
FROM system.metric_log WHERE event_date = today()
GROUP BY h ORDER BY h
┌───────────────────h─┬─user_time─┬─bar───────────────────────────────────────────────┐
│ 2019-09-05 04:12:00 │ 0 │ │
│ 2019-09-05 04:13:00 │ 0 │ │
│ 2019-09-05 04:14:00 │ 524000 │ ▋ │
│ 2019-09-05 04:15:00 │ 15880000 │ █████████████████████▏ │
│ 2019-09-05 04:19:00 │ 36724000 │ ████████████████████████████████████████████████▊ │
│ 2019-09-05 04:20:00 │ 17508000 │ ███████████████████████▎ │
│ 2019-09-05 04:21:00 │ 0 │ │
│ 2019-09-05 04:22:00 │ 0 │ │
│ 2019-09-05 04:23:00 │ 0 │ │
│ 2019-09-05 04:24:00 │ 0 │ │
│ 2019-09-05 04:25:00 │ 0 │ │
│ 2019-09-05 04:26:00 │ 0 │ │
│ 2019-09-05 04:27:00 │ 0 │ │
│ 2019-09-05 04:28:00 │ 0 │ │
│ 2019-09-05 04:29:00 │ 80000 │ │
│ 2019-09-05 04:30:00 │ 0 │ │
│ 2019-09-05 04:31:00 │ 0 │ │
Запоминает места в коде, в которых находилось выполнение запроса
в каждом потоке выполнения, в каждый момент времени с заданной периодичностью.
Если запрос тормозит — то каким местом?
— Где проводит время конкретный запрос?
— Где проводят время запросы некоторого вида?
— Где проводят время запросы конкретного пользователя?
— Где проводят время все запросы на кластере?
Разработчик — Никита Лапков, ВШЭ; и другие.
1. Выставляем одну или обе из этих настроек:
SET query_profiler_cpu_time_period_ns = 1000000;
SET query_profiler_real_time_period_ns = 1000000;
2. Выполняем запросы.
Данные сохраняются в таблицу system.trace_log.
event_date: 2019-09-05
event_time: 2019-09-05 05:47:44
revision: 54425
timer_type: CPU
thread_number: 149
query_id: b1d8e7f9-48d8-4cb3-a768-0a6683f6f061
trace: [140171472847748,61781958,110943821,117594728,117595220,115654933,
120321783,63251928,111161800,120329436,120331356,120308294,120313436,120319113,
120143313,115666412,120146905,111013972,118237176,111013972,117990912,111013972,
110986070,110986938,61896391,61897898,61887509,156206624,140171472807643]
trace — массив адресов в машинном коде (стек трейс);
Преобразовать адрес в имя функции:
— demangle(addressToSymbol(trace[1]))
Преобразовать адрес в имя файла и номер строки:
— addressToLine(trace[1])
* не забудьте установить clickhouse-common-static-dbg
Пример: топ функций:
SELECT count(),
demangle(addressToSymbol(trace[1] AS addr)) AS symbol
FROM system.trace_log
WHERE event_date = today()
GROUP BY symbol
ORDER BY count() DESC LIMIT 10
Пример: топ функций:
┌─count()─┬─symbol──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 517 │ void LZ4::(anonymous namespace)::decompressImpl<32ul, false>(char const*, char*, unsigned long) │
│ 480 │ void DB::deserializeBinarySSE2<4>(DB::PODArray<unsigned char, 4096ul, Allocator<false, false>, 15ul, 16ul>&, DB::PODArray<unsigned long, 4096ul, Allocator<false, false>, 15ul, 16ul>&, DB::ReadBuffer&, unsigned long) │
│ 457 │ DB::VolnitskyBase<true, true, DB::StringSearcher<true, true> >::search(unsigned char const*, unsigned long) const │
│ 270 │ read │
│ 163 │ void LZ4::(anonymous namespace)::decompressImpl<16ul, true>(char const*, char*, unsigned long) │
│ 130 │ void LZ4::(anonymous namespace)::decompressImpl<16ul, false>(char const*, char*, unsigned long) │
│ 58 │ CityHash_v1_0_2::CityHash128WithSeed(char const*, unsigned long, std::pair<unsigned long, unsigned long>) │
│ 44 │ void DB::deserializeBinarySSE2<2>(DB::PODArray<unsigned char, 4096ul, Allocator<false, false>, 15ul, 16ul>&, DB::PODArray<unsigned long, 4096ul, Allocator<false, false>, 15ul, 16ul>&, DB::ReadBuffer&, unsigned long) │
│ 37 │ void LZ4::(anonymous namespace)::decompressImpl<8ul, true>(char const*, char*, unsigned long) │
│ 32 │ memcpy │
└─────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Пример: топ контекстов выполнения для запроса:
SELECT count(),
arrayStringConcat(arrayMap(x -> concat(
demangle(addressToSymbol(x)),
'\n ',
addressToLine(x)), trace), '\n') AS sym
FROM system.trace_log
WHERE query_id = '1a1272b5-695a-4b17-966d-a1701b61b3eb'
AND event_date = today()
GROUP BY trace
ORDER BY count() DESC
LIMIT 10
count(): 154
sym: DB::VolnitskyBase<true, true, DB::StringSearcher<true, true> >::search(unsigned char const*, unsigned long) const
/opt/milovidov/ClickHouse/build_gcc9/dbms/programs/clickhouse
DB::MatchImpl<true, false>::vector_constant(DB::PODArray<unsigned char, 4096ul, Allocator<false, false>, 15ul, 16ul> const&, DB::PODArray<unsigned long, 4096ul, Allocator<false, false>, 15ul, 16ul> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, DB::PODArray<unsigned char, 4096ul, Allocator<false, false>, 15ul, 16ul>&)
/opt/milovidov/ClickHouse/build_gcc9/dbms/programs/clickhouse
DB::FunctionsStringSearch<DB::MatchImpl<true, false>, DB::NameLike>::executeImpl(DB::Block&, std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned long, unsigned long)
/opt/milovidov/ClickHouse/build_gcc9/dbms/programs/clickhouse
DB::PreparedFunctionImpl::execute(DB::Block&, std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned long, unsigned long, bool)
/home/milovidov/ClickHouse/build_gcc9/../dbms/src/Functions/IFunction.cpp:464
DB::ExpressionAction::execute(DB::Block&, bool) const
/usr/local/include/c++/9.1.0/bits/stl_vector.h:677
DB::ExpressionActions::execute(DB::Block&, bool) const
/home/milovidov/ClickHouse/build_gcc9/../dbms/src/Interpreters/ExpressionActions.cpp:759
DB::FilterBlockInputStream::readImpl()
/home/milovidov/ClickHouse/build_gcc9/../dbms/src/DataStreams/FilterBlockInputStream.cpp:84
DB::IBlockInputStream::read()
/usr/local/include/c++/9.1.0/bits/stl_vector.h:108
DB::ExpressionBlockInputStream::readImpl()
/home/milovidov/ClickHouse/build_gcc9/../dbms/src/DataStreams/ExpressionBlockInputStream.cpp:34
DB::IBlockInputStream::read()
/usr/local/include/c++/9.1.0/bits/stl_vector.h:108
DB::ParallelInputsProcessor<DB::ParallelAggregatingBlockInputStream::Handler>::thread(std::shared_ptr<DB::ThreadGroupStatus>, unsigned long)
/usr/local/include/c++/9.1.0/bits/atomic_base.h:419
ThreadFromGlobalPool::ThreadFromGlobalPool<void (DB::ParallelInputsProcessor<DB::ParallelAggregatingBlockInputStream::Handler>::*)(std::shared_ptr<DB::ThreadGroupStatus>, unsigned long), DB::ParallelInputsProcessor<DB::ParallelAggregatingBlockInputStream::Handler>*, std::shared_ptr<DB::ThreadGroupStatus>, unsigned long&>(void (DB::ParallelInputsProcessor<DB::ParallelAggregatingBlockInputStream::Handler>::*&&)(std::shared_ptr<DB::ThreadGroupStatus>, unsigned long), DB::ParallelInputsProcessor<DB::ParallelAggregatingBlockInputStream::Handler>*&&, std::shared_ptr<DB::ThreadGroupStatus>&&, unsigned long&)::{lambda()#1}::operator()() const
/usr/local/include/c++/9.1.0/bits/shared_ptr_base.h:729
ThreadPoolImpl<std::thread>::worker(std::_List_iterator<std::thread>)
/usr/local/include/c++/9.1.0/bits/atomic_base.h:551
execute_native_thread_routine
/home/milovidov/ClickHouse/ci/workspace/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/unique_ptr.h:81
start_thread
/lib/x86_64-linux-gnu/libpthread-2.27.so
clone
/build/glibc-OTsEL5/glibc-2.27/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:97
SELECT * FROM file(
'logs*_{000..999}.tsv',
TSV,
's String, x UInt8')
Множество файлов автоматически обрабатывается параллельно.
— ещё даже не помержено.
CentOS, RedHat... ГосЛинукс.
Поддерживаемые версии начиная от CentOS 5.
sudo yum install yum-utils
sudo rpm --import \
https://repo.yandex.ru/clickhouse/CLICKHOUSE-KEY.GPG
sudo yum-config-manager --add-repo \
https://repo.yandex.ru/clickhouse/rpm/stable/x86_64
sudo yum install clickhouse-server clickhouse-client
Изменение настроек таблиц налету
Функция neighbor
OS schedule priority
Table function VALUES
COLUMNS matcher
Live View
Каскадные Materialized Views
Нормальная логика AND/OR с NULL
Нормальная логика join_use_nulls
Правильный учёт оперативки запросами
Обновление DNS кэша
Settings constraints
Row Level security
Мутации не мешают мержам
Параллельная загрузка кусков
Оптимизация GROUP BY
Ускорение математических функций от Михаила Парахина
Ускорение функций для работы с JSON
Загрузка словарей не мешает друг другу
Оптимизация Merge таблиц
CREATE TABLE AS table_function()
— TTL для таблиц и отдельных столбцов;
— MySQL протокол;
— Adaptive granularity;
— Вторичные индексы;
— Функции текстового поиска;
— Функции для работы с JSON;
— WITH ROLLUP / WITH CUBE;
— ASOF JOIN;
— Поддержка гибридных хранилищ для свежих и старых данных;
— Создание и манипуляция словарями с помощью DDL запросов;
— Использование Z-Order для индексирования;
— Импорт и экспорт данных в S3;
— Параллельный парсинг форматов данных;
— Табличная функция input;
— Ускорение разбора VALUES с выражениями;
— Начальная реализация RBAC;
— Начальная реализация Merge JOIN;
— Не начальная реализация RBAC;
— Не начальная реализация Merge JOIN;
— Workload management;
Развитие Replicated таблиц:
— Wait-free ALTER ADD/DROP;
— ALTER RENAME COLUMN;
— полиморфные куски таблиц;
— поддержка мелких вставок;
— кворумный INSERT без линеаризуемости;
— INSERT без доступного ZooKeeper;
— отказ от хранения в ZooKeeper информации о кусках;
— альтернатива использованию ZooKeeper;
— VFS и хранение старых данных в S3;
— нормальная поддержка JBOD;
— эластичный кластер;
— ALTER MATERIALIZED VIEW;
— оптимизация GROUP BY с учётом сортированности таблицы;
— функции обработки временных рядов;
— функции для статистических тестов;
— модификаторы DISTINCT и ORDER BY для всех агрегатных функций;
— прототип GPU offloading;
— пережатие старых данных в фоне;
— минимальная поддержка транзакций для множества вставок/чтений;
— реплицируемые базы данных;
UDF на C++ и Rust.
Оконные функции.
Поддержка некоторых видов зависимых подзапросов.
Web site: https://clickhouse.com/
Maillist: [email protected]
YouTube: https://www.youtube.com/c/ClickHouseDB
Telegram chat: https://telegram.me/clickhouse_ru, clickhouse_en
GitHub: https://github.com/ClickHouse/ClickHouse/
Twitter: https://twitter.com/ClickHouseDB
Google groups: https://groups.google.com/forum/#!forum/clickhouse