> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> `QueryRunner` 테이블에 삽입된 레코드는 엔진이 로컬 또는 원격 클러스터에서 "fire and forget" 모드로 실행하는 쿼리를 나타냅니다.

# QueryRunner 테이블 엔진

`QueryRunner` 테이블에 삽입된 레코드는 엔진이 실행하는 쿼리를 나타냅니다.
이 엔진은 비동기 쿼리 실행, 생성된 쿼리의 일괄 실행,
원격 클러스터로의 쿼리 전달, 벤치마크, 퍼징, 그리고 섀도 트래픽을 사용한 테스트에 활용할 수 있습니다.

<div id="creating-a-table">
  ## 테이블 생성
</div>

```sql theme={null}
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 }];
```

테이블은 허용된 컬럼 중 일부만 포함하여 생성해야 합니다: `query`, `database`, `settings`.
컬럼 `query`는 필수이며, 나머지 컬럼은 선택 사항입니다.

| 컬럼         | 유형                    | 의미                                                 |
| ---------- | --------------------- | -------------------------------------------------- |
| `query`    | `String`              | 실행할 쿼리입니다.                                         |
| `database` | `String`              | 쿼리에 사용할 기본 데이터베이스입니다. 비어 있으면 서버의 기본 데이터베이스가 사용됩니다. |
| `settings` | `Map(String, String)` | 쿼리에 적용할 설정입니다.                                     |

<div id="engine-settings">
  ## 엔진 설정
</div>

| 설정               | 기본값              | 의미                                                                                                                                          |
| ---------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `cluster`        | `''`             | 쿼리를 전송할 클러스터 이름입니다. 비어 있으면 쿼리는 로컬에서 실행됩니다.                                                                                                  |
| `shard`          | `'1'`            | 쿼리를 전송할 클러스터 세그먼트의 1부터 시작하는 인덱스입니다. 쿼리마다 임의의 세그먼트를 선택하려면 `'random'`, 각 쿼리를 모든 세그먼트에서 실행하려면 `'all'`을 사용합니다. 이 설정을 사용하려면 `cluster` 설정이 필요합니다. |
| `mode`           | `'asynchronous'` | `synchronous` 모드에서는 삽입된 배치의 모든 쿼리가 완료된 후 INSERT가 반환됩니다. `asynchronous` 모드에서는 쿼리가 큐에 들어가는 즉시 INSERT가 반환됩니다.                                  |
| `threads`        | `4`              | 쿼리를 실행하는 백그라운드 스레드 수입니다.                                                                                                                    |
| `max_queue_size` | `1000`           | 큐에 대기할 수 있는 쿼리의 최대 개수입니다. 큐가 가득 차면 새로 삽입된 쿼리는 버려지고 오류가 기록됩니다.                                                                               |

<div id="details">
  ## 세부 사항
</div>

이 테이블은 `INSERT` 쿼리만 허용합니다.
쿼리는 "fire and forget" 모드로 실행됩니다. 예외가 발생해도 재시도는 수행되지 않으며,
SELECT 쿼리 결과는 폐기됩니다(결과를 유지하는 유일한 방법은 `INSERT SELECT`뿐입니다).
각 쿼리의 성공 여부는 `system.query_log` 테이블에서 확인할 수 있으며, 이 엔진이 시작한
쿼리는 initiating server에서 `is_internal = 1`로 표시됩니다.

큐에 들어간 쿼리는 메모리에 보관되며 server가 재시작되면 유지되지 않습니다. server 종료 시
(또는 table에 대해 `DROP`/`DETACH`를 수행할 때), 아직 시작되지 않은 쿼리는 폐기됩니다. 이미 실행 중인
쿼리 중 클러스터로 전달된 것은 취소되고, 로컬에서 실행 중인 것은 완료될 때까지 기다립니다.

실행할 쿼리 자체가 `INSERT`인 경우, 데이터는 인라인이어야 합니다. 즉 `INSERT ... VALUES (...)`,
`INSERT ... SELECT ...` 또는 쿼리 텍스트에 데이터가 포함된 `INSERT ... FORMAT ...` 형식이어야 합니다. 별도
stream에서 데이터를 받는 `INSERT`는 지원되지 않습니다.

<div id="local-mode-and-sql-security">
  ## Local mode 및 SQL SECURITY
</div>

`cluster` 설정이 없으면 쿼리는 로컬 서버에서 실행됩니다.
어떤 사용자로 실행되는지는 `SQL SECURITY` 절에 따라 결정됩니다.

* `INVOKER` (기본값): 쿼리는 `INSERT`를 수행한 사용자를 대신하여 실행됩니다.
* `DEFINER`: 쿼리는 지정된 `DEFINER` 사용자를 대신하여 실행됩니다. 삽입되는 쿼리는 임의의 쿼리일 수 있으므로, 이러한 테이블에 `INSERT`를 부여하면 definer의 모든 권한이 위임됩니다.
* `NONE`: 쿼리는 사용자 없이 전체 접근 권한으로 실행됩니다. 테이블 생성 시 `ALLOW_SQL_SECURITY_NONE` grant가 필요합니다.

<div id="cluster-mode">
  ## 클러스터 모드
</div>

`cluster` 설정을 지정하면 쿼리가 지정된 클러스터로 전송됩니다.

대상 세그먼트는 `shard`로 선택됩니다. 고정된 1-based 인덱스(기본값 `'1'`), 각 쿼리마다 임의의 세그먼트를 선택하는 `'random'`, 또는 클러스터의 모든 세그먼트에서 각 쿼리를 실행하는 `'all'`을 지정할 수 있습니다. 세그먼트 내 레플리카는 서버의 `load_balancing` 설정에 따라 선택됩니다.

`database` 컬럼은 원격 서버 연결의 기본 데이터베이스를 설정합니다. 기본 데이터베이스는 연결마다 한 번만 설정되므로, 서로 다른 각 `database` 값은 자체 연결 풀을 사용합니다. 이 연결 풀은 처음 사용할 때 생성되며 테이블의 수명 동안 재사용됩니다.

`DEFINER`와 `SQL SECURITY`는 로컬 모드에서만 적용되며, 이를 `cluster` 설정과 함께 사용하면 오류가 발생합니다. 원격 서버에서는 클러스터 구성의 자격 증명을 사용해 쿼리를 인증하며, 일반적인 초기 쿼리로 실행합니다. 이 쿼리는 `system.query_log`에 `is_initial_query = 1` 및 자체 `query_id`와 함께 기록됩니다(이를 생성한 INSERT와 연결되지 않음). initiating server에서는 dispatched 쿼리가 `system.query_log`에 `is_internal = 1`로 기록됩니다.

이 엔진은 쿼리 결과를 버리므로, 항상 dispatched 쿼리를 `discard_query_data = 1`로 실행합니다. 따라서 SELECT 쿼리의 결과 데이터는 네트워크를 통해 전송되지 않습니다(이는 `settings` 컬럼에 설정된 `discard_query_data` 값을 재정의합니다).

<div id="waiting-for-queries-to-finish">
  ## 쿼리가 완료될 때까지 대기
</div>

비동기 모드에서는 지금까지 해당 테이블에 제출된 모든 쿼리가 완료될 때까지 대기하도록 다음 쿼리를 사용할 수 있습니다:

```sql theme={null}
SYSTEM WAIT QUERY RUNNER runner;
```

<div id="example">
  ## 예시
</div>

쿼리 로그에 기록된 최근 `SELECT` 쿼리를 다시 실행합니다:

```sql theme={null}
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;
```
