> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-home-button.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> `clickhouse-go` 客户端的完整逐项配置参考，涵盖连接级、上下文级和批次选项。

# Go 客户端配置参考

本页列出了 `clickhouse-go` v2.x 中所有可配置选项。若需查看包含代码示例的指南，请参阅[配置](/zh/integrations/language-clients/go/configuration)。

<Info>
  **版本标注**

  在 `clickhouse-go` v2.35.0 及更高版本中新增的选项，会在其说明旁标注 *(自 vX.Y.Z 起)*。没有 “Since” 标记的选项自 v2.0 起即已可用，并包含在所有受支持的版本中。
</Info>

<div id="how-options-are-set">
  ## 选项的设置方式
</div>

选项可在三个作用范围内设置：

| 作用范围   | 设置方式                                    | 生效时长      |
| ------ | --------------------------------------- | --------- |
| **连接** | `clickhouse.Options` 结构体或 DSN 字符串       | 该连接上的所有查询 |
| **查询** | 带有 `WithXxx` 函数的 `clickhouse.Context()` | 单次查询执行    |
| **批次** | `PrepareBatch()` 选项函数                   | 单次批次操作    |

当多个作用范围重叠时，范围越具体，优先级越高：**批次 > 查询 > 连接**。对于 `Settings`，查询级别的键会与连接级别的键合并；如果发生冲突，则以查询级别为准。

**通过 Options 结构体：**

```go theme={null}
conn, err := clickhouse.Open(&clickhouse.Options{
    Addr:        []string{"localhost:9000"},
    Auth:        clickhouse.Auth{Database: "default", Username: "default", Password: ""},
    DialTimeout: 10 * time.Second,
    Compression: &clickhouse.Compression{Method: clickhouse.CompressionLZ4},
})
```

**通过 DSN 连接字符串：**

```go theme={null}
db, err := sql.Open("clickhouse", "clickhouse://user:pass@localhost:9000/default?dial_timeout=10s&compress=lz4")
```

**通过 Connector (使用 Options 结构体的 `database/sql`) ：**

```go theme={null}
db := sql.OpenDB(clickhouse.Connector(&clickhouse.Options{
    Addr:        []string{"localhost:9000"},
    Auth:        clickhouse.Auth{Database: "default", Username: "default"},
    DialTimeout: 10 * time.Second,
}))
// 创建后设置仅适用于 database/sql 的连接池参数
db.SetConnMaxIdleTime(5 * time.Minute)
```

**通过 Context (按查询) ：**

```go theme={null}
ctx := clickhouse.Context(context.Background(),
    clickhouse.WithQueryID("my-query-123"),
    clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
rows, err := conn.Query(ctx, "SELECT ...")
```

***

<div id="connection-options">
  ## 连接选项
</div>

<div id="protocol-and-connection">
  ### 协议和连接
</div>

| 选项                 | 类型                         | 默认值                                                       | DSN 参数                                                           | 描述                                                                                | 最佳实践                                                                                                                                                                                       | 配置错误时                                                                                       |
| ------------------ | -------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
| `Protocol`         | `Protocol` (int)           | `Native`                                                  | 协议方案：`clickhouse://`=Native，`http://`=HTTP                       | 通信协议：`Native` (0) 用于 TCP，`HTTP` (1) 用于 HTTP                                       | `Native` 的性能通常高约 30%，应优先使用。若需要支持 proxy、穿过 firewall (80/443 端口) ，或使用仅 HTTP 支持的压缩 (`gzip`/`br`) ，请使用 `HTTP`。参见 [TCP 与 HTTP](/zh/integrations/language-clients/go/configuration#tcp-vs-http)。 | HTTP 协议方案配 Native 端口 (9000) ：connection refused。`Native` 被 firewall 阻止：发生 timeout。          |
| `Addr`             | `[]string`                 | `["localhost:9000"]` (Native) `["localhost:8123"]` (HTTP) | URL 中以逗号分隔的主机                                                    | 用于连接和故障转移的 `"host:port"` 地址列表                                                     | 在 production 环境中指定多个地址以实现高可用。正确端口：9000 (`Native`)、8123 (`HTTP`)、9440 (`Native`+`TLS`)、8443 (`HTTP`+`TLS`)。                                                                                 | 单个地址：无故障转移。端口错误：`"connection refused"`。空值/nil：默认使用 localhost，在分布式部署中会失败。                    |
| `ConnOpenStrategy` | `ConnOpenStrategy` (uint8) | `ConnOpenInOrder` (0)                                     | `connection_open_strategy` (`in_order`, `round_robin`, `random`) | 从 `Addr` 中选择 server 的策略。`InOrder` (0)=故障转移，`RoundRobin` (1)=负载均衡，`Random` (2)=随机。 | 主备场景使用 `InOrder`。双活/K8s 场景使用 `RoundRobin`。为避免惊群效应，可使用 `Random`。                                                                                                                            | 在双活场景中使用 `InOrder`：第一台 server 会承受全部负载，其他 server 处于 idle。所有策略在失败时都会尝试所有 server——只影响*优先*尝试哪个。 |

***

<div id="authentication">
  ### 身份验证
</div>

| 选项              | 类型                          | 默认值               | DSN 参数                        | 说明                                                                                  | 最佳实践                                            | 配置错误时                                                                              |
| --------------- | --------------------------- | ----------------- | ----------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------- |
| `Auth.Username` | `string`                    | `"default"`       | `username` 或 URL 用户部分         | 用于 ClickHouse 身份验证的用户名                                                              | 生产环境中绝不要使用 `default`。请创建权限最小化的专用用户。             | 用户名错误：`"Code: 516. DB::Exception: Authentication failed"`。空字符串：会静默使用 `"default"`。  |
| `Auth.Password` | `string`                    | `""`              | `password` 或 URL 密码部分         | 用于 ClickHouse 身份验证的密码                                                               | 生产环境中请使用环境变量或 secret 管理器。在 DSN 中对特殊字符进行 URL 编码。 | 密码错误：`"Code: 516. DB::Exception: Authentication failed"`。特殊字符未进行 URL 编码：会出现解析错误。   |
| `Auth.Database` | `string`                    | `""` (server 默认值) | `database` 或 URL 路径 (`/mydb`) | connection 的默认数据库                                                                   | 始终显式指定。生产环境中请为每个应用使用专用数据库。                      | 不存在：`"Code: 81. DB::Exception: Database xyz doesn't exist"`。在多租户设置中留空：查询会落到错误的数据库。 |
| `GetJWT`        | `func(ctx) (string, error)` | `nil`             | (仅可通过程序方式设置)                  | 返回用于 ClickHouse Cloud 身份验证的 JWT 的回调。可通过 `WithJWT(token)` 为每个查询覆盖。* (自 v2.35.0 起) *  | 实现标记缓存/刷新——它会在每次 connection/request 时调用。        | 标记过期：会出现身份验证错误。阻塞式回调：会导致超时。JWT 的优先级高于用户名/密码。需要 TLS——否则会静默回退到用户名/密码。                |

```go theme={null}
GetJWT: func(ctx context.Context) (string, error) {
    return getTokenFromVault(ctx)
}
```

***

<div id="timeouts">
  ### 超时
</div>

| 选项            | 类型              | 默认值         | DSN 参数         | 说明                                                       | 最佳实践                                        | 配置不当时                                                                                   |
| ------------- | --------------- | ----------- | -------------- | -------------------------------------------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------- |
| `DialTimeout` | `time.Duration` | `30s`       | `dial_timeout` | 建立新连接的最长等待时间。达到 `MaxOpenConns` 时，它也控制从连接池获取连接的等待时间。      | LAN 环境下为 5-10 秒，WAN/云环境下为 15-30 秒。切勿低于 1 秒。 | 过短：拥塞期间出现 `"clickhouse: acquire conn timeout"`。过长 (> 60 秒) ：故障期间应用会一直挂起。                |
| `ReadTimeout` | `time.Duration` | `5m` (300s) | `read_timeout` | 单次 read 调用等待服务器响应的最长时间。按每个块生效，而非整个查询。`Context` 截止时间优先生效。 | 较短的交互式查询设为 10-30 秒；较长的分析型查询设为 5-30 分钟。      | 过短：查询中途出现 `"i/o timeout"` 或 `"read: connection reset by peer"`；服务器仍会继续执行。过长：无法及时检测失效连接。 |

***

<div id="connection-pool">
  ### 连接池
</div>

| 选项                | 类型              | 默认值                        | DSN 参数              | API              | 说明                                                                           | 最佳实践                                                                                                         | 配置不当时                                                                                                                             |
| ----------------- | --------------- | -------------------------- | ------------------- | ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `MaxIdleConns`    | `int`           | `5`                        | `max_idle_conns`    | 两者               | 连接池中空闲 (未使用但仍保持存活) 的最大连接数                                                    | 设为预期并发查询数的 50-80%。低：2-5，中：10-20，高：20-50。                                                                     | 过低：连接频繁创建和销毁，延迟升高。过高：浪费内存。会自动受 `MaxOpenConns` 限制。                                                                                 |
| `MaxOpenConns`    | `int`           | `MaxIdleConns + 5` (默认：10) | `max_open_conns`    | 两者               | 最大连接总数 (空闲 + 活跃)                                                             | 低：10-20，中：20-50，高：50-100。公式：并发查询数 + 突发量 + 缓冲。监控：`SELECT * FROM system.metrics WHERE metric='TCPConnection'`。 | 过低：`"clickhouse: acquire conn timeout"`。过高：服务器报错 `"Too many connections"`，并可能超出 FD 限制。ClickHouse 默认 `max_connections`：1024 (共享) 。 |
| `ConnMaxLifetime` | `time.Duration` | `1h`                       | `conn_max_lifetime` | 两者               | 连接可复用的最长时间。在归还到连接池时检查。                                                       | 稳定环境建议 1-5h。K8s/滚动部署建议 5-15m。切勿设为无限。                                                                         | 过短 (\< 1m) ：频繁创建和销毁连接，延迟升高。过长/无限：连接陈旧、无法感知 DNS 变更，流量也不会重新均衡。                                                                      |
| `ConnMaxIdleTime` | `time.Duration` | `0` (无)                    | —                   | 仅 `database/sql` | 连接在关闭前允许保持*空闲*的最长时间。不在 `Options` struct 中——需通过 `db.SetConnMaxIdleTime()` 设置。 | 对于 K8s/突发型 workload，建议设为 5-10m，以便在流量峰值后回收空闲连接。                                                               | 未设置：空闲连接会一直保留到 `ConnMaxLifetime`。过短 (\< 30s) ：即使在正常空档期间也会重建连接。                                                                    |

<Info>
  **仅适用于 database/sql**

  `ConnMaxIdleTime` 是 Go 标准 `database/sql` 连接池设置。它不在 `clickhouse.Options` struct 中，也不能通过 `clickhouse.Open()` 设置。请在 `OpenDB()` 之后设置：

  ```go theme={null}
  db := clickhouse.OpenDB(&clickhouse.Options{...})
  db.SetConnMaxIdleTime(5 * time.Minute)
  ```
</Info>

用法详见 [连接池](/zh/integrations/language-clients/go/configuration#connection-pooling)。

***

<div id="sql-db-settings">
  ### 标准 database/sql 连接池设置
</div>

使用 `clickhouse.OpenDB()` 或 `sql.Open("clickhouse", dsn)` 时，返回的 `*sql.DB` 支持 Go 的标准连接池方法。`OpenDB()` 会自动应用 `Options` 中的前三项：

| 方法                         | 对应的 Options 配置    | 说明                |
| -------------------------- | ----------------- | ----------------- |
| `db.SetMaxIdleConns(n)`    | `MaxIdleConns`    | 由 `OpenDB()` 自动应用 |
| `db.SetMaxOpenConns(n)`    | `MaxOpenConns`    | 由 `OpenDB()` 自动应用 |
| `db.SetConnMaxLifetime(d)` | `ConnMaxLifetime` | 由 `OpenDB()` 自动应用 |
| `db.SetConnMaxIdleTime(d)` | *None*            | 必须在创建后手动设置        |

<Info>
  **ClickHouse API (clickhouse.Open)**

  `clickhouse.Open()` 返回的连接不支持这些方法。ClickHouse API 会直接使用 `Options` 结构体中的字段，在内部管理自己的连接池。
</Info>

***

<div id="compression">
  ### 压缩
</div>

| 选项                     | 类型                         | 默认值                 | DSN 参数                                                                         | 描述                                                         | 最佳实践                                                                                                  | 配置不当时                                                                              |
| ---------------------- | -------------------------- | ------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `Compression.Method`   | `CompressionMethod` (byte) | None                | `compress` (`lz4`, `zstd`, `lz4hc`, `gzip`, `deflate`, `br`，或使用 `true` 表示 LZ4) | 用于数据传输的压缩算法。请参见下方的协议支持矩阵。                                  | LAN：None 或 LZ4。WAN：ZSTD 或 LZ4。CPU 资源受限：LZ4。追求最高压缩率：ZSTD (Native) 或 Brotli (HTTP) 。对于小于 1 MB 的插入可跳过压缩。 | 在 Native 上使用 GZIP/Brotli：握手失败。在 HTTP 上使用 LZ4HC：报错或静默回退。慢速网络上不使用压缩：插入速度会慢 10-100 倍。 |
| `Compression.Level`    | `int`                      | `3`                 | `compress_level`                                                               | 算法对应的压缩强度。GZIP/Deflate：-2 到 9。Brotli：0 到 11。LZ4/ZSTD：会被忽略。 | GZIP 的平衡设置：3-6。Brotli 的平衡设置：4-6。                                                                      | 级别过高：CPU 开销极大、收益很小。对 LZ4/ZSTD 设为非零：会被静默忽略。未启用压缩时设置 Level：无效果。                      |
| `MaxCompressionBuffer` | `int` (bytes)              | `10485760` (10 MiB) | `max_compression_buffer`                                                       | 刷写前允许使用的最大压缩缓冲区大小。每个连接都有自己的缓冲区。                            | 默认 10 MiB 通常就足够。对于宽行可设为 20-50 MiB。总内存 = buffer x `MaxOpenConns`。                                      | 过小 (\< 1 MiB) ：频繁刷写，效率较低。过大 (> 100 MiB)：连接较多时可能导致 OOM。                             |

**按协议划分的压缩方法支持情况：**

| 方法                   | Native | HTTP |
| -------------------- | ------ | ---- |
| `CompressionLZ4`     | 是      | 是    |
| `CompressionLZ4HC`   | 是      | 否    |
| `CompressionZSTD`    | 是      | 是    |
| `CompressionGZIP`    | 否      | 是    |
| `CompressionDeflate` | 否      | 是    |
| `CompressionBrotli`  | 否      | 是    |

***

<div id="tls">
  ### TLS
</div>

| 选项    | 类型            | 默认值        | DSN 参数                            | 描述                                                             | 最佳实践                                                                                                | 配置错误时                                                                                                                                                                                                                                                                              |
| ----- | ------------- | ---------- | --------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TLS` | `*tls.Config` | `nil` (明文) | `secure=true`, `skip_verify=true` | TLS/SSL 配置。非 `nil` 时启用 TLS。端口：Native 9000/9440，HTTP 8123/8443。 | 在生产环境和 ClickHouse Cloud 中务必启用 (必需) 。在生产环境中将 `InsecureSkipVerify` 设为 `false`。可通过 `RootCAs` 添加自定义 CA。 | 端口错误：`"connection reset by peer"`。在生产环境中使用 `skip_verify=true`：存在遭受 MITM 攻击的风险。证书已过期：`"x509: certificate has expired"`。主机名错误：`"x509: certificate is valid for X, not Y"`。CA 不受信任：`"x509: certificate signed by unknown authority"`。如果 HTTP DSN 使用了 `secure=true`：请改用 `https://` 协议。 |

代码示例请参见 [TLS](/zh/integrations/language-clients/go/configuration#using-tls)。

***

<div id="logging">
  ### 日志
</div>

| 选项                    | 类型                     | 默认值           | DSN 参数  | 描述                                                                                     | 最佳实践                                                       | 配置错误时                                  |
| --------------------- | ---------------------- | ------------- | ------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------- |
| `Logger`              | `*slog.Logger`         | `nil` (不记录日志) | —       | 通过 Go 的 `log/slog` 提供结构化日志记录器。优先级：`Debug`+`Debugf` > `Logger` > 空操作。* (自 v2.43.0 起) *  | 在生产环境中使用配备 JSON 处理器的 `slog`。使用 `logger.With(...)` 添加应用上下文。 | —                                      |
| `Debug` (deprecated)  | `bool`                 | `false`       | `debug` | 旧版调试开关。请改用 `Logger`。如果未设置 `Debugf`，日志将输出到 `stdout`。                                    | —                                                          | 在生产环境中启用：会带来性能开销、产生冗长日志，并可能在输出中包含敏感数据。 |
| `Debugf` (deprecated) | `func(string, ...any)` | `nil`         | —       | 自定义调试日志函数。请改用 `Logger`。要求设置 `Debug: true`。                                             | —                                                          | —                                      |

```go theme={null}
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
conn, err := clickhouse.Open(&clickhouse.Options{
    Logger: logger,
    // ...
})
```

完整示例请参见[日志](/zh/integrations/language-clients/go/configuration#logging)。

***

<div id="buffers-and-memory">
  ### 缓冲区与内存
</div>

| 选项                     | Type    | 默认值     | DSN 参数              | 按查询                       | 说明                        | 最佳实践                                               | 配置不当时                                                                    |
| ---------------------- | ------- | ------- | ------------------- | ------------------------- | ------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------ |
| `BlockBufferSize`      | `uint8` | `2`     | `block_buffer_size` | 是 (`WithBlockBufferSize`) | 读取结果时要缓冲的已解码块数。支持并发读取与解码。 | 默认值 2 即可。对于大型流式结果，可设为 5-10。内存 = 缓冲区 × 块大小 × 并发查询数。 | 过小 (1) ：会阻塞块读取器，延迟更高。过大 (> 50) ：内存占用高，收益递减。                              |
| `FreeBufOnConnRelease` | `bool`  | `false` | —                   | 否                         | 每次查询后释放连接的内存缓冲区，而不是复用。    | 查询频率高时使用 `false`。在内存受限的容器中，或不频繁处理大批次时，使用 `true`。   | `false` + 内存受限：缓冲区会累积 (内存 = 缓冲区 × 空闲连接数) 。`true` + 高速率：GC 压力增大，CPU 开销增加。 |

***

<div id="http-specific">
  ### HTTP 专用
</div>

<Warning>
  **在 Native 协议下会被静默忽略**

  这些选项仅影响 `Protocol: clickhouse.HTTP`。使用 Native 协议时，它们会被静默忽略，并且不会产生任何错误或警告。
</Warning>

| 选项                    | 类型                                                 | 默认值                   | DSN 参数                     | 说明                                                          | 最佳实践                                                    | 配置错误时                                                                    |
| --------------------- | -------------------------------------------------- | --------------------- | -------------------------- | ----------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------ |
| `HttpHeaders`         | `map[string]string`                                | `nil`                 | —                          | 为每个请求附加额外的 HTTP 请求头                                         | 用于 tracing (`X-Request-ID`) 或认证代理请求头。尽量保持最少。            | 覆盖内部请求头 (`Content-Type`、`Authorization`) ：行为不可预测。                        |
| `HttpUrlPath`         | `string`                                           | `""`                  | `http_path`                | 追加到请求上的 URL 路径。会自动添加前导 `/`。                                 | 在使用基于路径路由的 reverse proxy 时使用。                           | 路径错误：代理/LB 返回 HTTP 404。                                                  |
| `HttpMaxConnsPerHost` | `int`                                              | `0` (unlimited)       | —                          | 传输层每个主机的 TCP 连接数 (`http.Transport.MaxConnsPerHost`) 。       | 对大多数应用保留为 0。仅当 server 有严格的连接数限制时再设置。                    | 值过低 (例如 `MaxOpenConns`=50 时设为 10) ：会造成传输层瓶颈，即使 server 负载较低，queries 仍会变慢。 |
| `HTTPProxyURL`        | `*url.URL`                                         | `nil` (uses env vars) | `http_proxy` (URL-encoded) | 用于转发请求的 HTTP proxy                                          | 如果需要 proxy，请显式设置。它会覆盖 `HTTP_PROXY`/`HTTPS_PROXY` 环境变量。  | 地址错误：`"dial tcp: lookup proxy: no such host"`。proxy 需要认证：HTTP 407。       |
| `TransportFunc`       | `func(*http.Transport) (http.RoundTripper, error)` | `nil`                 | —                          | 自定义 HTTP transport 工厂。接收默认 transport 以便进行包装。*(自 v2.41.0 起)* | 用于可观测性中间件。不要覆盖 `Proxy`、`DialContext`、`TLSClientConfig`。 | 返回 `nil`：panic。覆盖客户端字段：TLS/proxy 会被静默忽略。阻塞式 RoundTripper：deadlocks。      |

<Info>
  **双层 HTTP 连接池**

  使用 HTTP 时，存在两个连接池：

  * **第 1 层 (应用层) ：** `MaxIdleConns` / `MaxOpenConns` -- 控制 `httpConnect` 对象
  * **第 2 层 (传输层) ：** `HttpMaxConnsPerHost` -- 控制底层 TCP 连接

  Native 协议采用简单的 1:1 映射，并会忽略 `HttpMaxConnsPerHost`。
</Info>

```go theme={null}
TransportFunc: func(t *http.Transport) (http.RoundTripper, error) {
    return &loggingRoundTripper{transport: t}, nil
}
```

***

<div id="advanced-connection">
  ### 高级连接
</div>

| 选项             | 类型                                                     | 默认值                   | DSN 参数 | 描述                                    | 最佳实践                                               | 配置不当时                                                               |
| -------------- | ------------------------------------------------------ | --------------------- | ------ | ------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------- |
| `DialContext`  | `func(ctx, addr) (net.Conn, error)`                    | `nil` (标准拨号器)         | —      | 用于 TCP 连接的自定义拨号函数。兼容 Native 和 HTTP。   | 在 99% 的情况下保持为 `nil`。可用于 Unix 套接字、SOCKS 代理和自定义 DNS。 | 不遵循上下文：会导致挂起和资源泄漏。设置了 `TLS` 时：自定义拨号器必须自行处理 TLS。`net.Conn` 无效：会导致崩溃。 |
| `DialStrategy` | `func(ctx, connID, options, dial) (DialResult, error)` | `DefaultDialStrategy` | —      | 自定义服务器选择和连接策略。会覆盖 `ConnOpenStrategy`。 | 在 99.9% 的情况下使用默认值。仅在需要地理感知路由、加权选择或健康检查时自定义。        | 未尝试所有服务器：即使有健康服务器可用也会失败。内部执行高开销操作：会在每次建立连接时阻塞连接池获取。                 |

***

<div id="client-information">
  ### 客户端信息
</div>

| Option       | Type                | Default                          | DSN param                       | Per-query               | Description                                                                                                          | Best practice                                                                                  | When misconfigured          |
| ------------ | ------------------- | -------------------------------- | ------------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------------------- |
| `ClientInfo` | `ClientInfo` struct | 自动：`clickhouse-go` 版本 + Go 运行时环境 | `client_info_product=myapp/1.0` | 是 (`WithClientInfo`，追加) | 发送给 ClickHouse 的应用标识信息。包含 `Products` (`[]struct{Name,Version}`) 和 `Comment` (`[]string`) 。可在 `system.query_log` 中看到。 | 始终设置应用名称和版本。查询归属示例：`SELECT client_name FROM system.query_log WHERE client_name LIKE '%myapp%'` | 未设置：在多服务环境中，无法识别是哪个服务发起了查询。 |

```go theme={null}
ClientInfo: clickhouse.ClientInfo{
    Products: []struct{ Name, Version string }{
        {Name: "my-service", Version: "1.0.0"},
    },
}
// 显示为：clickhouse-go/2.x my-service/1.0.0 (lv:go/1.23; os:linux)
```

***

<div id="server-settings">
  ### ClickHouse 服务器设置
</div>

| 选项              | 类型                            | 默认值   | DSN 参数                                 | 是否支持按查询设置                          | 说明                                                                              | 最佳实践                           | 配置错误时                                                                                                              |
| --------------- | ----------------------------- | ----- | -------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `Settings`      | `map[string]any`              | `nil` | 任何未识别的参数 (例如 `?max_execution_time=60`) | 是 (`WithSettings`，冲突时以 context 为准) | 应用于每个查询的 ClickHouse server settings。DSN 转换：`"true"`→`1`，`"false"`→`0`，数值→`int`。 | 在连接级别设置通用限制，再通过 context 按查询覆盖。 | 拼写错误：可能被静默忽略，也可能因版本不同而报错。类型错误：`"Cannot parse string 'abc' as Int64"`。`max_execution_time=0` 且未设置 deadline：查询会一直运行。 |
| `CustomSetting` | `CustomSetting{Value string}` | —     | —                                      | 是 (通过 `WithSettings`)              | 将某项设置标记为 "自定义" (非重要) 以用于 native protocol。即使服务器无法识别，也不会报错。HTTP 默认将所有设置都视为自定义。    | 用于 Experimental 或特定版本的设置。      | 将重要设置标记为自定义：如果不受支持，会被静默忽略。                                                                                         |

**常见设置：**

| 设置                   | 类型  | 说明                   |
| -------------------- | --- | -------------------- |
| `max_execution_time` | int | 查询超时时间 (秒)           |
| `max_memory_usage`   | int | 每个查询的内存限制 (字节)       |
| `max_block_size`     | int | 处理用块大小               |
| `readonly`           | int | 1 = 只读，2 = 只读 + 可改设置 |

```go theme={null}
Settings: clickhouse.Settings{
    "max_execution_time":  60,                                        // 重要 -- 未知时报错
    "my_custom_setting":   clickhouse.CustomSetting{Value: "value"},  // 自定义 -- 未知时忽略
}
```

***

<div id="context-options">
  ## Context 级别查询选项
</div>

使用 `clickhouse.Context()` 为每个查询单独设置：

```go theme={null}
ctx := clickhouse.Context(context.Background(),
    clickhouse.WithQueryID("my-query"),
    clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
```

<Info>
  **Context 截止时间的行为**

  如果 Context 的截止时间 > 1 秒，`max_execution_time` 会自动设为 `seconds_remaining + 5`。这会覆盖任何手动设置的值。
</Info>

| 选项                        | 类型                         | 默认值                 | 协议           | 描述                                                                                                                                     | 最佳实践                                                                                    | 配置不当时                                                                                                                       |
| ------------------------- | -------------------------- | ------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `WithQueryID`             | `string`                   | 自动生成                | 两者均支持        | 自定义查询 ID。可在 `system.query_log` 和 `system.processes` 中看到。                                                                               | 使用 UUID。便于执行 `KILL QUERY WHERE query_id='...'`。                                         | 重复的 ID：会导致 `system.query_log` 中出现混淆。                                                                                        |
| `WithQuotaKey`            | `string`                   | `""`                | 两者均支持        | 用于多租户资源限制的 QUOTA 键。需要服务器端 QUOTA 配置。                                                                                                    | 用于按客户或按用户设置限制。                                                                          | 未配置 Quota：会被静默忽略。                                                                                                           |
| `WithJWT`                 | `string`                   | `""`                | 仅支持 HTTPS    | ClickHouse Cloud 的单次查询 JWT 覆盖设置。*(自 v2.35.0 起)*                                                                                        | 适用于多租户代理中的单请求认证。                                                                        | 未启用 TLS：将被忽略，并回退到连接认证。已过期：`"Token has expired"`。                                                                            |
| `WithSettings`            | `Settings`                 | 继承连接设置              | 两者皆可         | 按查询设置的服务器级配置。会与 connection 级 Settings 合并；发生冲突时，以上下文为准。                                                                                 | 按查询类型覆盖 `max_execution_time` 或 `max_rows_to_read`。                                      | 与连接级 `Settings` 相同。                                                                                                         |
| `WithParameters`          | `参数` (`map[string]string`) | `nil`               | 两者皆可         | 服务器端参数化查询的参数值。查询语法：`{param_name:Type}`。                                                                                                | 为防止 SQL 注入，请使用此方式，而不要进行字符串拼接。                                                           | 参数缺失：`"Substitution {param_name:Type} isn't set"`。类型不匹配：`"Cannot parse string 'abc' as UInt64"`。                            |
| `WithAsync`               | `bool` (wait)              | 同步                  | 两者           | 异步 insert 模式。设置 `async_insert=1`。`wait=true` 时还会设置 `wait_for_async_insert=1`。需要 ClickHouse 21.11+。*(自 v2.41.0 起；取代旧版 `WithStdAsync`。)* | 用于高吞吐量插入。                                                                               | `wait=false`：错误可能会异步出现——请检查 `system.asynchronous_insert_log`。与 SELECT 一起使用时：会被忽略。旧 server：`"Unknown setting async_insert"`。 |
| `WithLogs`                | `func(*Log)`               | `nil`               | 仅支持 Native   | 查询执行期间的服务器日志条目回调。                                                                                                                      | 保持轻量快速——否则会阻塞执行。耗时较重的处理请使用 goroutine。                                                   | 在 HTTP 上：不会被调用，且不会有任何提示。                                                                                                    |
| `WithProgress`            | `func(*Progress)`          | `nil`               | 仅限原生协议       | 查询进度更新 (已处理的行数/字节数) 。                                                                                                                  | 务必保持处理快速——否则会阻塞执行。                                                                      | 在 HTTP 上：不会被调用，且不会有任何提示。                                                                                                    |
| `WithProfileInfo`         | `func(*ProfileInfo)`       | `nil`               | 仅适用于 Native  | 查询执行统计信息回调。                                                                                                                            | 务必保持轻量——否则会阻塞执行。                                                                        | 在 HTTP 上：不会被调用，且不会有任何提示。                                                                                                    |
| `WithProfileEvents`       | `func([]ProfileEvent)`     | `nil`               | 仅适用于 Native  | 性能计数器的回调函数。                                                                                                                            | 务必尽快返回——否则会阻塞执行。                                                                        | 在 HTTP 下：永远不会被调用，且不会有任何提示。                                                                                                  |
| `WithoutProfileEvents`    | —                          | 发送事件                | 仅原生协议        | 禁用 profile events。适用于 ≥ 25.11 服务器的性能优化。*(自 v2.44.0 起)*                                                                                 | 在不需要 profile events 时使用。                                                                | 在较旧的 server 上：会因设置未知而报错。                                                                                                    |
| `WithExternalTable`       | `...*ext.Table`            | `nil`               | 两者都支持        | 将临时查找表附加到查询中。数据按每次查询传输。                                                                                                                | 将表控制在 \< 10 MB 以内。原生协议比 HTTP (multipart) 更高效。                                           | 大表：每次查询的网络开销都较高。                                                                                                            |
| `WithUserLocation`        | `*time.Location`           | 服务器时区               | 两者均可         | 覆盖 DateTime 解析所用的时区。                                                                                                                   | 当客户端与服务端时区不一致时，应显式设置。                                                                   | 时区错误：DateTime 值会在无提示的情况下偏差数小时，并可能导致数据损坏。                                                                                    |
| `WithColumnNamesAndTypes` | `[]ColumnNameAndType`      | `nil` (执行 DESCRIBE) | 仅限 HTTP      | 在 HTTP 插入时，通过预先提供列信息，跳过 `DESCRIBE TABLE` 往返请求。 *(自 v2.37.0 起)*                                                                         | 在 schema 已知且稳定时使用。                                                                      | 类型不匹配：`"Cannot convert String to UInt64"`。迁移后发生 schema drift：列信息已过时。                                                        |
| `WithBlockBufferSize`     | `uint8`                    | connection 级别 (2)   | 两者皆可         | 为单个查询覆盖连接级别的 `BlockBufferSize`。                                                                                                        | 对于特定查询返回的大型结果集，可增大该值。                                                                   | —                                                                                                                           |
| `WithClientInfo`          | `ClientInfo`               | 连接级别                | 两者均支持        | 为单次查询附加额外的客户端信息。不会替换，只会追加。*(自 v2.42.0 起)*                                                                                              | 为每个请求添加上下文 (例如端点名称) 。                                                                   | —                                                                                                                           |
| `WithSpan`                | `trace.SpanContext`        | 为空                  | 仅限 Native 协议 | 用于分布式链路追踪的 OpenTelemetry span 上下文。                                                                                                     | 参阅 [OpenTelemetry](/zh/integrations/language-clients/go/clickhouse-api#open-telemetry)。 | —                                                                                                                           |

```go theme={null}
ctx := clickhouse.Context(ctx,
    clickhouse.WithQueryID("query-123"),
    clickhouse.WithParameters(clickhouse.Parameters{
        "user_id": "12345",
    }),
    clickhouse.WithProgress(func(p *clickhouse.Progress) {
        log.Printf("Progress: %d rows, %d bytes", p.Rows, p.Bytes)
    }),
)
rows, err := conn.Query(ctx, "SELECT * FROM users WHERE id = {user_id:String}")
```

***

<div id="batch-options">
  ## 批次选项
</div>

传递给 `PrepareBatch()`。导入：`github.com/ClickHouse/clickhouse-go/v2/lib/driver`。

| Option                  | Default           | Description                                                 | Best practice                          | When misconfigured                                 |
| ----------------------- | ----------------- | ----------------------------------------------------------- | -------------------------------------- | -------------------------------------------------- |
| `WithReleaseConnection` | 连接会一直持有到 `Send()` | 在 `PrepareBatch()` 后立即将连接释放回连接池。在 `Send()`/`Flush()` 时重新获取。 | 对于长时间存在的批次 (数分钟/数小时) ，建议使用此选项以防止连接池耗尽。 | 长批次未使用此选项：如果活跃连接很多，可能会出现 `"acquire conn timeout"`。 |
| `WithCloseOnFlush`      | 批次保持打开状态          | 调用 `Flush()` 时自动关闭批次。                                       | 适用于一次性批次。可省去显式调用 `Close()`。            | 与多次 `Flush()` 调用一起使用时：第一次 flush 会关闭批次，后续操作会失败。     |

```go theme={null}
batch, err := conn.PrepareBatch(ctx, "INSERT INTO table",
    driver.WithReleaseConnection(),
    driver.WithCloseOnFlush(),
)
```

***

<div id="quick-reference-tables">
  ## 速查表
</div>

<div id="pool-sizing">
  ### 连接池大小建议
</div>

| 应用类型          | MaxIdleConns | MaxOpenConns | ConnMaxLifetime |
| ------------- | ------------ | ------------ | --------------- |
| 低流量 Web 应用    | 5            | 10           | 1h              |
| 中等流量 API      | 20           | 50           | 30m             |
| 高流量服务         | 50           | 100          | 15m             |
| 后台批次作业        | 10           | 20           | 2h              |
| Kubernetes 部署 | 10           | 20           | 10m             |
| 无服务器 (Lambda) | 1            | 5            | 5m              |

<div id="timeout-recommendations">
  ### 超时建议
</div>

| 环境         | DialTimeout | ReadTimeout |
| ---------- | ----------- | ----------- |
| 本地 / 局域网   | 5s          | 30s         |
| Cloud，同一区域 | 10s         | 2m          |
| Cloud，跨区域  | 30s         | 5m          |
| OLAP 工作负载  | 10s         | 30m         |
| 实时 / OLTP  | 5s          | 10s         |

<div id="dsn-parameters">
  ### DSN 参数速查
</div>

| DSN 参数                     | Options 字段               | 示例                                      |
| -------------------------- | ------------------------ | --------------------------------------- |
| `username`                 | `Auth.Username`          | `?username=admin`                       |
| `password`                 | `Auth.Password`          | `?password=secret`                      |
| `database`                 | `Auth.Database`          | `?database=mydb` 或路径中的 `/mydb`          |
| `dial_timeout`             | `DialTimeout`            | `?dial_timeout=10s`                     |
| `read_timeout`             | `ReadTimeout`            | `?read_timeout=5m`                      |
| `max_open_conns`           | `MaxOpenConns`           | `?max_open_conns=50`                    |
| `max_idle_conns`           | `MaxIdleConns`           | `?max_idle_conns=20`                    |
| `conn_max_lifetime`        | `ConnMaxLifetime`        | `?conn_max_lifetime=30m`                |
| `connection_open_strategy` | `ConnOpenStrategy`       | `?connection_open_strategy=round_robin` |
| `block_buffer_size`        | `BlockBufferSize`        | `?block_buffer_size=10`                 |
| `compress`                 | `Compression.Method`     | `?compress=lz4`                         |
| `compress_level`           | `Compression.Level`      | `?compress_level=6`                     |
| `max_compression_buffer`   | `MaxCompressionBuffer`   | `?max_compression_buffer=20971520`      |
| `secure`                   | `TLS`                    | `?secure=true`                          |
| `skip_verify`              | `TLS.InsecureSkipVerify` | `?skip_verify=true`                     |
| `debug`                    | `Debug`                  | `?debug=true`                           |
| `client_info_product`      | `ClientInfo.Products`    | `?client_info_product=myapp/1.0`        |
| `http_proxy`               | `HTTPProxyURL`           | `?http_proxy=http%3A%2F%2Fproxy%3A8080` |
| `http_path`                | `HttpUrlPath`            | `?http_path=/clickhouse`                |
| *(其他任意参数)*                 | `Settings[key]`          | `?max_execution_time=60`                |

***

<div id="troubleshooting">
  ## 故障排查
</div>

<div id="acquire-conn-timeout">
  ### 连接池耗尽："acquire conn timeout"
</div>

\*\*原因：\*\*连接池已耗尽——所有 `MaxOpenConns` 连接都在使用中，且在 `DialTimeout` 期限内没有连接可用。

**解决方法**

请按顺序尝试以下步骤，并在调整参数前先排查根本原因：

1. 检查是否有长时间运行并占用连接的查询：`SELECT query_id, elapsed FROM system.processes ORDER BY elapsed DESC`。如果有，先处理这些慢查询。
2. 如果你运行的是长生命周期的批次 (从 `PrepareBatch()` 到 `Send()` 之间相隔数分钟或数小时) ，请使用 `WithReleaseConnection()`，以便在批次保持打开期间将连接归还到连接池。
3. 增加 `MaxOpenConns`，使其与实际观测到的并发度相匹配。
4. 仅当预期会出现突发流量，且等待获取连接确实是瓶颈时，才增加 `DialTimeout`。

<div id="io-timeout">
  ### 读取超时和连接重置错误
</div>

**原因：** 等待服务器响应时超过了 `ReadTimeout`，或者连接被服务器/网络关闭。

**解决方法：**

* 对长时间运行的查询增大 `ReadTimeout`
* 使用 Context deadline 控制每个查询的超时时间
* 检查 ClickHouse 服务端的 `max_execution_time` 限制

<div id="auth-failed">
  ### "Code: 516. 身份验证失败"
</div>

**原因：** 用户名或密码错误，或者用户不存在。

**解决方法：**

* 对照 `system.users` 表核实凭据
* 检查 DSN 密码中的特殊字符是否存在 URL 编码问题
* 确认该用户有权访问指定数据库

<div id="tls-errors">
  ### TLS 证书错误
</div>

| 错误                                              | 原因        | 解决方法                                   |
| ----------------------------------------------- | --------- | -------------------------------------- |
| `x509: certificate has expired`                 | 服务器证书已过期  | 更新服务器证书                                |
| `x509: certificate is valid for X, not Y`       | 主机名不匹配    | 使用正确的主机名，或将其添加到 SANs                   |
| `x509: certificate signed by unknown authority` | CA 不受信任   | 将 CA 添加到 `tls.Config.RootCAs`          |
| `connection reset by peer`                      | TLS/端口不匹配 | TLS 请使用 9440 (Native) 或 8443 (HTTP) 端口 |

<div id="memory-growth">
  ### 内存逐渐增长
</div>

**原因：** 空闲连接的缓冲区大量积累。

**解决方法：**

* 在内存受限的环境中设置 `FreeBufOnConnRelease: true`
* 减少 `MaxIdleConns` 以限制空闲连接数
* 如果使用压缩，减小 `MaxCompressionBuffer`
* 调低 `ConnMaxLifetime`，让连接更频繁地轮换
