Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Motor de tabela QueryRunner

Registros inseridos em uma tabela QueryRunner representam consultas que o motor executa. O motor pode ser usado para execução assíncrona de consultas, execução em lote de consultas geradas, direcionamento de consultas para clusters remotos, benchmarks, fuzzing e testes com tráfego espelhado.

Criando uma tabela

CREATE TABLE runner
(
    query String,
    database String,
    settings Map(LowCardinality(String), String)
)
ENGINE = QueryRunner
SETTINGS
    cluster = 'cluster_name',
    shard = '1',
    mode = 'asynchronous',
    threads = 4,
    max_queue_size = 1000
[DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER | NONE }];

A tabela deve ser criada com um subconjunto das colunas permitidas: query, database, settings. A coluna query é obrigatória, e as demais colunas são opcionais.

Coluna Tipo Significado
query String A consulta a ser executada.
database String O banco de dados padrão da consulta. Se estiver vazio, será usado o banco de dados padrão do servidor.
settings Map(String, String) Configurações aplicadas à consulta.

Configurações do motor

Configuração Padrão Significado
cluster '' Nome do cluster para o qual as consultas serão enviadas. Se estiver vazio, as consultas serão executadas localmente.
shard '1' Índice com base em 1 do shard do cluster para o qual as consultas serão enviadas, ou 'random' para escolher um shard aleatório por consulta, ou 'all' para executar cada consulta em todos os shards. Requer a configuração cluster.
mode 'asynchronous' No modo synchronous, INSERT retorna depois que todas as consultas do lote inserido forem concluídas. No modo asynchronous, INSERT retorna assim que as consultas entram na fila.
threads 4 Número de threads em segundo plano que executam as consultas.
max_queue_size 1000 Número máximo de consultas na fila. Quando a fila está cheia, novas consultas inseridas são descartadas, e um erro é registrado.

Detalhes

A tabela permite apenas consultas INSERT. As consultas são executadas no modo "fire and forget": em caso de exceção, não há novas tentativas, e os resultados das consultas SELECT são descartados (a única forma de preservar os resultados é INSERT SELECT). O sucesso de cada consulta pode ser verificado na tabela system.query_log, onde as consultas iniciadas por este motor são marcadas com is_internal = 1 no servidor iniciador.

As consultas enfileiradas são mantidas na memória e não sobrevivem à reinicialização do servidor. No desligamento do servidor (ou em um DROP/DETACH da tabela), as consultas que ainda não tiverem sido iniciadas serão descartadas. Das consultas que já estiverem em execução, aquelas enviadas para um cluster são canceladas, enquanto as que estiverem em execução localmente são aguardadas até terminarem.

Quando uma consulta a ser executada é, ela própria, um INSERT, seus dados devem estar inline — INSERT ... VALUES (...), INSERT ... SELECT ... ou INSERT ... FORMAT ... com os dados no texto da consulta. Um INSERT que receba seus dados de um fluxo separado não tem suporte.

Modo local e SQL SECURITY

Sem a configuração cluster, as consultas são executadas no servidor local. O usuário com cujas permissões elas são executadas é determinado pela cláusula SQL SECURITY:

  • INVOKER (padrão): as consultas são executadas em nome do usuário que realizou o INSERT.
  • DEFINER: as consultas são executadas em nome do usuário DEFINER especificado. Como as consultas inseridas são arbitrárias, conceder INSERT em uma tabela desse tipo delega todos os privilégios do definidor.
  • NONE: as consultas são executadas com acesso total, sem usuário. Requer o privilégio ALLOW_SQL_SECURITY_NONE na criação da tabela.

Modo cluster

Quando a configuração cluster é especificada, as consultas são enviadas ao cluster especificado.

O shard de destino é selecionado por shard: um índice fixo começando em 1 ('1' por padrão), 'random' para escolher um shard aleatório para cada consulta, ou 'all' para executar cada consulta em todos os shards do cluster. A réplica dentro do shard é escolhida de acordo com a configuração load_balancing do servidor.

A coluna database define o banco de dados padrão da conexão com o servidor remoto. Como o banco de dados padrão é definido uma vez por conexão, cada valor distinto de database usa seu próprio pool de conexões, que é criado no primeiro uso e reutilizado durante todo o ciclo de vida da tabela.

DEFINER e SQL SECURITY têm efeito apenas no modo local, e combiná-los com a configuração cluster é um erro. Nos servidores remotos, as consultas são autenticadas com as credenciais da configuração do cluster e executadas como consultas iniciais normais: elas são registradas em system.query_log com is_initial_query = 1 e seu próprio query_id (não vinculado ao INSERT que as produziu). No servidor iniciador, as consultas encaminhadas são registradas em system.query_log com is_internal = 1.

Como o motor descarta os resultados das consultas, ela sempre executa as consultas encaminhadas com discard_query_data = 1, portanto os dados de resultado de consultas SELECT não são transferidos pela rede (isso substitui qualquer valor de discard_query_data definido na coluna settings).

Aguardando a conclusão das consultas

No modo assíncrono, a consulta a seguir pode ser usada para bloquear a execução até que todas as consultas enviadas à tabela até o momento sejam concluídas:

SYSTEM WAIT QUERY RUNNER runner;

Exemplo

Reexecutando consultas SELECT recentes do log de consultas:

INSERT INTO runner (query, database, settings)
SELECT query, current_database, Settings
FROM system.query_log
WHERE type = 'QueryFinish' AND is_initial_query AND NOT is_internal AND query_kind = 'Select'
  AND event_time > now() - INTERVAL 1 HOUR;
Navigation