Pular para o conteúdo principal

Caso 1: INSERT em uma partição, de uma tabela, da família MergeTree*

Isso é transacional (ACID) se as linhas inseridas estiverem agrupadas e forem inseridas como um único bloco (consulte as Notas):
  • Atomicidade: um INSERT é concluído com êxito ou rejeitado por completo: se uma confirmação for enviada ao cliente, então todas as linhas foram inseridas; se um erro for enviado ao cliente, então nenhuma linha foi inserida.
  • Consistência: se nenhuma restrição da tabela for violada, então todas as linhas de um INSERT serão inseridas e o INSERT será concluído com êxito; se as restrições forem violadas, então nenhuma linha será inserida.
  • Isolamento: clientes concorrentes observam um snapshot consistente da tabela — o estado da tabela como era antes da tentativa de INSERT ou após o INSERT bem-sucedido; nenhum estado parcial é visto. Clientes dentro de outra transação têm isolamento por snapshot, enquanto clientes fora de uma transação têm nível de isolamento read uncommitted.
  • Durabilidade: um INSERT bem-sucedido é gravado no sistema de arquivos antes de responder ao cliente, em uma única réplica ou em várias réplicas (controlado pela configuração insert_quorum), e o ClickHouse pode solicitar ao SO que sincronize os dados do sistema de arquivos na mídia de armazenamento (controlado pela configuração fsync_after_insert).
  • INSERT em várias tabelas com uma única instrução é possível se houver visões materializadas envolvidas (o INSERT do cliente é feito em uma tabela que tem visões materializadas associadas).

Caso 2: INSERT em múltiplas partições de uma tabela da família MergeTree*

O mesmo que o Caso 1 acima, com este detalhe:
  • Se a tabela tiver muitas partições e o INSERT abranger muitas delas, então a inserção em cada partição será transacional por si só

Caso 3: INSERT em uma tabela distribuída da família MergeTree*

O mesmo que o Caso 1 acima, com este detalhe:
  • O INSERT em uma tabela distribuída não é transacional como um todo, enquanto a inserção em cada shard é transacional

Caso 4: Usando uma tabela Buffer

  • inserções em tabelas Buffer não são atômicas, isoladas, consistentes nem duráveis

Caso 5: Usando async_insert

O mesmo que o Caso 1 acima, com este detalhe:
  • a atomicidade é garantida mesmo que async_insert esteja habilitado e wait_for_async_insert esteja definido como 1 (o padrão), mas, se wait_for_async_insert estiver definido como 0, a atomicidade não é garantida.

Notas

  • as linhas inseridas pelo cliente em algum formato de dados são empacotadas em um único bloco quando:
    • o formato de inserção é baseado em linhas (como CSV, TSV, Values, JSONEachRow etc.) e os dados contêm menos de max_insert_block_size linhas (~1 000 000 por padrão) ou menos de min_chunk_bytes_for_parallel_parsing bytes (10 MB por padrão), caso o parsing paralelo esteja em uso (habilitado por padrão)
    • o formato de inserção é baseado em colunas (como Native, Parquet, ORC etc.) e os dados contêm apenas um bloco de dados
  • o tamanho do bloco inserido, em geral, pode depender de muitas configurações (por exemplo: max_block_size, max_insert_block_size, min_insert_block_size_rows, min_insert_block_size_bytes, preferred_block_size_bytes etc.)
  • se o cliente não recebeu uma resposta do servidor, ele não sabe se a transação foi bem-sucedida e pode repeti-la usando as propriedades de inserção exactly-once
  • o ClickHouse usa MVCC com isolamento por snapshot internamente para transações concorrentes
  • todas as propriedades ACID continuam válidas mesmo em caso de encerramento/falha do servidor
  • insert_quorum em diferentes AZs ou fsync deve estar habilitado para garantir inserts duráveis em uma configuração típica
  • a “consistência” nos termos ACID não cobre a semântica de sistemas distribuídos; veja https://jepsen.io/consistency, que é controlada por diferentes configurações (select_sequential_consistency)
  • esta explicação não cobre um novo recurso de transações que permite ter transações completas em várias tabelas, visões materializadas, para múltiplos SELECTs etc. (veja a próxima seção sobre Transactions, Commit, and Rollback)

Transações, Commit e Rollback

Além da funcionalidade descrita no início deste documento, o ClickHouse oferece suporte experimental a transações, commit e rollback.

Requisitos

  • Implante o ClickHouse Keeper ou o ZooKeeper para rastrear transações
  • Somente DB atomic (padrão)
  • Somente o mecanismo de tabela MergeTree não replicado
  • Ative o suporte experimental a transações adicionando esta configuração em config.d/transactions.xml:

Observações

  • Este é um recurso experimental, e é esperado que haja mudanças.
  • Se ocorrer uma exceção durante uma transação, você não poderá confirmar a transação. Isso inclui todas as exceções, inclusive exceções UNKNOWN_FUNCTION causadas por erros de digitação.
  • Transações aninhadas não são compatíveis; finalize a transação atual e inicie uma nova

Configuração

Estes exemplos consideram um servidor ClickHouse de nó único com o ClickHouse Keeper habilitado.

Ative o suporte experimental a transações

/etc/clickhouse-server/config.d/transactions.xml

Configuração básica para um único nó do servidor ClickHouse com o ClickHouse Keeper habilitado

Consulte a documentação de implantação para saber mais sobre como implantar o servidor ClickHouse e um quórum adequado de nós do ClickHouse Keeper. A configuração mostrada aqui é apenas para fins experimentais.
/etc/clickhouse-server/config.d/config.xml

Exemplo

Verifique se as transações experimentais estão habilitadas

Execute um BEGIN TRANSACTION ou START TRANSACTION, seguido de um ROLLBACK, para verificar se as transações experimentais estão habilitadas e se o ClickHouse Keeper também está habilitado, já que ele é usado para rastrear transações.
Se você vir o erro abaixo, verifique o arquivo de configuração para garantir que allow_experimental_transactions esteja definido como 1 (ou qualquer valor diferente de 0 ou false).
Você também pode verificar o ClickHouse Keeper executando:
O ClickHouse Keeper deve responder com imok.

Crie uma tabela para teste

A criação de tabelas não é transacional. Execute esta consulta DDL fora de uma transação.

Inicie uma transação e insira uma linha

Você pode consultar a tabela dentro de uma transação e ver que a linha foi inserida, embora a transação ainda não tenha sido confirmada.

Desfaça a transação e consulte a tabela novamente

Verifique se a transação foi desfeita:

Conclua uma transação e consulte a tabela novamente

Introspecção de transações

Você pode inspecionar as transações consultando a tabela system.transactions, mas observe que não é possível consultar essa tabela em uma sessão que esteja em uma transação. Abra uma segunda sessão do clickhouse client para consultar essa tabela.

Mais detalhes

Consulte esta meta issue para ver testes muito mais abrangentes e acompanhar o andamento.
Última modificação em 25 de junho de 2026