Перейти к основному содержимому
Перейти к основному содержимому

Поддержка транзакций (ACID)

Случай 1: INSERT в один раздел одной таблицы семейства MergeTree*

Это транзакционно (ACID), если вставленные строки упаковываются и вставляются как один блок (см. Заметки):

  • Атомарность: оператор INSERT выполняется полностью или отклоняется: если подтверждение отправлено клиенту, значит, все строки были вставлены; если клиенту отправлена ошибка, значит, строки не были вставлены.
  • Последовательность: если не нарушены ограничения таблицы, все строки в INSERT вставляются, и INSERT выполняется успешно; если ограничения нарушены, строки не вставляются.
  • Изолированность: одновременно работающие клиенты наблюдают согласованный снимок таблицы — состояние таблицы соответствует либо состоянию до попытки INSERT, либо после успешного INSERT; частичное состояние не отображается. Клиенты внутри другой транзакции имеют изоляцию по снимкам, в то время как клиенты вне транзакции имеют уровень изоляции чтения неподтвержденных.
  • Долговечность: успешный INSERT записывается в файловую систему перед ответом клиенту, на одной реплике или нескольких репликах (управляется настройкой insert_quorum), и ClickHouse может попросить операционную систему синхронизировать данные файловой системы на носителе (управляется настройкой fsync_after_insert).
  • INSERT в несколько таблиц с одним оператором возможен, если задействованы материализованные представления (INSERT от клиента идет в таблицу, которая имеет связанные материализованные представления).

Случай 2: INSERT в несколько разделов одной таблицы семейства MergeTree*

То же, что и в Случае 1, с этой деталью:

  • Если у таблицы много разделов, и INSERT охватывает много разделов, то вставка в каждый раздел транзакционна сама по себе.

Случай 3: INSERT в одну распределенную таблицу семейства MergeTree*

То же, что и в Случае 1, с этой деталью:

  • INSERT в распределенную таблицу не является транзакционным в целом, в то время как вставка в каждую шардированную часть является транзакционной.

Случай 4: Использование таблицы Buffer

  • вставка в таблицы Buffer не является ни атомарной, ни изолированной, ни последовательной, ни долговечной.

Случай 5: Использование async_insert

То же, что и в Случае 1, с этой деталью:

  • атомарность гарантируется даже если включен async_insert, и wait_for_async_insert установлен в 1 (по умолчанию), но если wait_for_async_insert установлен в 0, то атомарность не гарантируется.

Заметки

  • строки, вставленные клиентом в каком-либо формате данных, упаковываются в один блок, когда:
    • формат вставки основан на строках (например, CSV, TSV, Values, JSONEachRow и т. д.) и данные содержат менее max_insert_block_size строк (~1 000 000 по умолчанию) или менее min_chunk_bytes_for_parallel_parsing байт (10 МБ по умолчанию) в случае использования параллельного парсинга (включен по умолчанию)
    • формат вставки основан на столбцах (например, Native, Parquet, ORC и т. д.) и данные содержат только один блок данных.
  • размер вставленного блока может зависеть от многих настроек (например: max_block_size, max_insert_block_size, min_insert_block_size_rows, min_insert_block_size_bytes, preferred_block_size_bytes и т. д.)
  • если клиент не получил ответа от сервера, клиент не знает, успешна ли транзакция, и он может повторить транзакцию, используя свойства вставки точно один раз.
  • ClickHouse использует MVCC с изоляцией по снимкам для одновременных транзакций.
  • все свойства ACID действительны даже в случае аварийной остановки сервера.
  • либо insert_quorum в разные AZ, либо fsync должны быть включены для обеспечения долговечных вставок в типовой настройке.
  • "последовательность" в терминах ACID не охватывает семантику распределенных систем, см. https://jepsen.io/consistency, что контролируется различными настройками (select_sequential_consistency).
  • это объяснение не охватывает новую функциональность транзакций, которая позволяет иметь полнофункциональные транзакции по нескольким таблицам, материализованным представлениям для нескольких SELECT и т. д. (см. следующий раздел о Транзакциях, Подтверждении и Откате).

Транзакции, Подтверждение и Откат

Experimental feature. Learn more.
Not supported in ClickHouse Cloud

В дополнение к функциональности, описанной в начале этого документа, ClickHouse имеет экспериментальную поддержку для транзакций, подтверждений и функциональности отката.

Требования

  • Разверните ClickHouse Keeper или ZooKeeper для отслеживания транзакций.
  • Только атомарные БД (по умолчанию).
  • Только движок таблицы Non-Replicated MergeTree.
  • Включите экспериментальную поддержку транзакций, добавив эту настройку в config.d/transactions.xml:

Заметки

  • Это экспериментальная функция, и следует ожидать изменений.
  • Если во время транзакции произойдет исключение, вы не можете подтвердить транзакцию. Это касается всех исключений, включая исключения UNKNOWN_FUNCTION, вызванные опечатками.
  • Вложенные транзакции не поддерживаются; завершите текущую транзакцию и начните новую.

Конфигурация

Эти примеры для сервера ClickHouse с одним узлом с включенным ClickHouse Keeper.

Включите экспериментальную поддержку транзакций

Основная конфигурация для одного сервера ClickHouse с включенным ClickHouse Keeper

примечание

Смотрите документацию развертывания для получения подробной информации о развертывании сервера ClickHouse и правильного кворума узлов ClickHouse Keeper. Показанная здесь конфигурация предназначена для экспериментальных целей.

Пример

Проверьте, что экспериментальные транзакции включены

Выдайте BEGIN TRANSACTION или START TRANSACTION, за которым следует ROLLBACK, чтобы проверить, что экспериментальные транзакции включены, и что ClickHouse Keeper включен, так как он используется для отслеживания транзакций.

подсказка

Если вы видите следующее сообщение об ошибке, проверьте свой конфигурационный файл, чтобы убедиться, что allow_experimental_transactions установлен в 1 (или любое значение, отличное от 0 или false).

Вы также можете проверить ClickHouse Keeper, выполнив

ClickHouse Keeper должен ответить imok.

Создайте таблицу для тестирования

подсказка

Создание таблиц не является транзакционным. Выполните этот DDL-запрос вне транзакции.

Начните транзакцию и вставьте строку

примечание

Вы можете выполнять запрос к таблице из транзакции и увидеть, что строка была вставлена, даже если она еще не была зафиксирована.

Откатите транзакцию и снова выполните запрос к таблице

Проверьте, что транзакция откатена:

Завершите транзакцию и снова выполните запрос к таблице

Инспекция транзакций

Вы можете инспектировать транзакции, выполнив запрос к таблице system.transactions, но обратите внимание, что вы не можете выполнять запросы к этой таблице из сессии, которая находится в транзакции. Откройте второй сеанс clickhouse client, чтобы выполнить запрос к этой таблице.

Более подробная информация

Смотрите эту главную проблему, чтобы найти более обширные тесты и оставаться в курсе хода работы.