本页列出了 clickhouse-go v2.x 中所有可配置选项。若需查看包含代码示例的指南,请参阅配置。
版本标注在 clickhouse-go v2.35.0 及更高版本中新增的选项,会在其说明旁标注 (自 vX.Y.Z 起)。没有 “Since” 标记的选项自 v2.0 起即已可用,并包含在所有受支持的版本中。
选项可在三个作用范围内设置:
| 作用范围 | 设置方式 | 生效时长 |
|---|
| 连接 | clickhouse.Options 结构体或 DSN 字符串 | 该连接上的所有查询 |
| 查询 | 带有 WithXxx 函数的 clickhouse.Context() | 单次查询执行 |
| 批次 | PrepareBatch() 选项函数 | 单次批次操作 |
当多个作用范围重叠时,范围越具体,优先级越高:批次 > 查询 > 连接。对于 Settings,查询级别的键会与连接级别的键合并;如果发生冲突,则以查询级别为准。
通过 Options 结构体:
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 连接字符串:
db, err := sql.Open("clickhouse", "clickhouse://user:pass@localhost:9000/default?dial_timeout=10s&compress=lz4")
通过 Connector (使用 Options 结构体的 database/sql) :
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 (按查询) :
ctx := clickhouse.Context(context.Background(),
clickhouse.WithQueryID("my-query-123"),
clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
rows, err := conn.Query(ctx, "SELECT ...")
| 选项 | 类型 | 默认值 | 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。 | 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——只影响优先尝试哪个。 |
| 选项 | 类型 | 默认值 | 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——否则会静默回退到用户名/密码。 |
GetJWT: func(ctx context.Context) (string, error) {
return getTokenFromVault(ctx)
}
| 选项 | 类型 | 默认值 | 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";服务器仍会继续执行。过长:无法及时检测失效连接。 |
| 选项 | 类型 | 默认值 | 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) :即使在正常空档期间也会重建连接。 |
仅适用于 database/sqlConnMaxIdleTime 是 Go 标准 database/sql 连接池设置。它不在 clickhouse.Options struct 中,也不能通过 clickhouse.Open() 设置。请在 OpenDB() 之后设置:db := clickhouse.OpenDB(&clickhouse.Options{...})
db.SetConnMaxIdleTime(5 * time.Minute)
用法详见 连接池。
使用 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 | 必须在创建后手动设置 |
ClickHouse API (clickhouse.Open)clickhouse.Open() 返回的连接不支持这些方法。ClickHouse API 会直接使用 Options 结构体中的字段,在内部管理自己的连接池。
| 选项 | 类型 | 默认值 | 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 | 否 | 是 |
| 选项 | 类型 | 默认值 | 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。
| 选项 | 类型 | 默认值 | 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。 | — | — |
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
conn, err := clickhouse.Open(&clickhouse.Options{
Logger: logger,
// ...
})
完整示例请参见日志。
| 选项 | Type | 默认值 | DSN 参数 | 按查询 | 说明 | 最佳实践 | 配置不当时 |
|---|
BlockBufferSize | uint8 | 2 | block_buffer_size | 是 (WithBlockBufferSize) | 读取结果时要缓冲的已解码块数。支持并发读取与解码。 | 默认值 2 即可。对于大型流式结果,可设为 5-10。内存 = 缓冲区 × 块大小 × 并发查询数。 | 过小 (1) :会阻塞块读取器,延迟更高。过大 (> 50) :内存占用高,收益递减。 |
FreeBufOnConnRelease | bool | false | — | 否 | 每次查询后释放连接的内存缓冲区,而不是复用。 | 查询频率高时使用 false。在内存受限的容器中,或不频繁处理大批次时,使用 true。 | false + 内存受限:缓冲区会累积 (内存 = 缓冲区 × 空闲连接数) 。true + 高速率:GC 压力增大,CPU 开销增加。 |
在 Native 协议下会被静默忽略这些选项仅影响 Protocol: clickhouse.HTTP。使用 Native 协议时,它们会被静默忽略,并且不会产生任何错误或警告。
| 选项 | 类型 | 默认值 | 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。 |
双层 HTTP 连接池使用 HTTP 时,存在两个连接池:
- 第 1 层 (应用层) :
MaxIdleConns / MaxOpenConns — 控制 httpConnect 对象
- 第 2 层 (传输层) :
HttpMaxConnsPerHost — 控制底层 TCP 连接
Native 协议采用简单的 1:1 映射,并会忽略 HttpMaxConnsPerHost。
TransportFunc: func(t *http.Transport) (http.RoundTripper, error) {
return &loggingRoundTripper{transport: t}, nil
}
| 选项 | 类型 | 默认值 | 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% 的情况下使用默认值。仅在需要地理感知路由、加权选择或健康检查时自定义。 | 未尝试所有服务器:即使有健康服务器可用也会失败。内部执行高开销操作:会在每次建立连接时阻塞连接池获取。 |
| 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%' | 未设置:在多服务环境中,无法识别是哪个服务发起了查询。 |
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)
| 选项 | 类型 | 默认值 | 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 = 只读 + 可改设置 |
Settings: clickhouse.Settings{
"max_execution_time": 60, // 重要 -- 未知时报错
"my_custom_setting": clickhouse.CustomSetting{Value: "value"}, // 自定义 -- 未知时忽略
}
使用 clickhouse.Context() 为每个查询单独设置:
ctx := clickhouse.Context(context.Background(),
clickhouse.WithQueryID("my-query"),
clickhouse.WithSettings(clickhouse.Settings{"max_execution_time": 60}),
)
Context 截止时间的行为如果 Context 的截止时间 > 1 秒,max_execution_time 会自动设为 seconds_remaining + 5。这会覆盖任何手动设置的值。
| 选项 | 类型 | 默认值 | 协议 | 描述 | 最佳实践 | 配置不当时 |
|---|
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。 | — |
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}")
传递给 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 会关闭批次,后续操作会失败。 |
batch, err := conn.PrepareBatch(ctx, "INSERT INTO table",
driver.WithReleaseConnection(),
driver.WithCloseOnFlush(),
)
| 应用类型 | 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 |
| 环境 | DialTimeout | ReadTimeout |
|---|
| 本地 / 局域网 | 5s | 30s |
| Cloud,同一区域 | 10s | 2m |
| Cloud,跨区域 | 30s | 5m |
| OLAP 工作负载 | 10s | 30m |
| 实时 / OLTP | 5s | 10s |
| 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 |
连接池耗尽:“acquire conn timeout”
**原因:**连接池已耗尽——所有 MaxOpenConns 连接都在使用中,且在 DialTimeout 期限内没有连接可用。
解决方法
请按顺序尝试以下步骤,并在调整参数前先排查根本原因:
- 检查是否有长时间运行并占用连接的查询:
SELECT query_id, elapsed FROM system.processes ORDER BY elapsed DESC。如果有,先处理这些慢查询。
- 如果你运行的是长生命周期的批次 (从
PrepareBatch() 到 Send() 之间相隔数分钟或数小时) ,请使用 WithReleaseConnection(),以便在批次保持打开期间将连接归还到连接池。
- 增加
MaxOpenConns,使其与实际观测到的并发度相匹配。
- 仅当预期会出现突发流量,且等待获取连接确实是瓶颈时,才增加
DialTimeout。
原因: 等待服务器响应时超过了 ReadTimeout,或者连接被服务器/网络关闭。
解决方法:
- 对长时间运行的查询增大
ReadTimeout
- 使用 Context deadline 控制每个查询的超时时间
- 检查 ClickHouse 服务端的
max_execution_time 限制
原因: 用户名或密码错误,或者用户不存在。
解决方法:
- 对照
system.users 表核实凭据
- 检查 DSN 密码中的特殊字符是否存在 URL 编码问题
- 确认该用户有权访问指定数据库
| 错误 | 原因 | 解决方法 |
|---|
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) 端口 |
原因: 空闲连接的缓冲区大量积累。
解决方法:
- 在内存受限的环境中设置
FreeBufOnConnRelease: true
- 减少
MaxIdleConns 以限制空闲连接数
- 如果使用压缩,减小
MaxCompressionBuffer
- 调低
ConnMaxLifetime,让连接更频繁地轮换