Skip to main content
RemoteRemoteSecure 数据库引擎可通过原生 TCP 协议实时访问远程 ClickHouse 服务器上某个数据库中的表。它们相当于 ClickHouse 到 ClickHouse 场景下的 MySQLPostgreSQL 数据库引擎。 表列表及其结构会按需从远程服务器拉取 (底层使用 SHOW TABLESDESCRIBE TABLE) ,因此该数据库始终反映远程服务器的当前状态。每个表都会以 Distributed 存储的形式提供,该存储基于所提供的地址构建临时集群,并将 SELECTINSERT 查询转发至远程服务器。 这对于联合多个 ClickHouse 集群,或将较大的 ClickHouse 集群接入 clickhouse-local 或较小的集群非常方便。

创建数据库

如果省略端口,Remote 将通过普通 TCP 端口连接 (tcp_port,默认值为 9000) 。
引擎参数
  • addresses_expr — 远程服务器地址,或用于生成多个地址的表达式,格式为 hosthost:port。地址表达式支持与 remote 表函数相同的 glob 模式 (例如 {a,b,c}{N..M}{a|b},可展开为多个分片和副本) 。如果省略端口,Remote 使用普通 TCP 端口 (tcp_port,默认值为 9000) ,RemoteSecure 使用安全 TCP 端口 (tcp_port_secure,默认值为 9440) 。
  • database — 远程服务器上的数据库名称。
  • user — 远程用户名。可选,默认值:default
  • password — 远程用户密码。可选,默认值:空。
地址和凭据存储在数据库定义中,因此 SHOW CREATE DATABASE 会隐藏密码。与 remote 表函数一样,指向当前服务器的地址会被视为本地分片:SELECTINSERT 会直接以当前用户身份执行,因此该用户必须拥有底层数据库及其表的相应特权;存储的凭据仅用于真正的远程服务器。如果某个分片的本地副本没有该数据库或表,查找将像 Distributed 表一样回退到该分片的远程副本。在这种情况下,SHOW CREATE TABLE 输出的是实际生效的回退地址 (从各分片中剔除本地副本) ,而非配置的地址,因此生成的 Remote(...) 表定义能够重建实际处理查询的对象。 当地址表达式描述多个分片时,每个代理表都会从所有分片读取,但元数据——表列表及其结构——与 remote 表函数一样,取自任意一个分片 (优先本地分片) ,这样列出表只需执行一次查询,而不是每个分片执行一次。因此,集群中的各分片应提供相同的一组表;如果某张表仅存在于部分分片上,对该表的代理查询会在没有该表的分片上失败。向多分片数据库中的表执行 INSERT 时,每一行都会被发送到随机分片 (代理 Distributed 表具有隐式的 rand() 分片键) ;若要为查询指定分片,请设置 insert_shard_id。该隐式键仅用于分配插入的行:读取时,该表的行为与没有分片键的 Distributed 表相同 (尤其是,optimize_skip_unused_shardsforce_optimize_skip_unused_shards 不会将其视为分片裁剪键) 。SHOW CREATE TABLE 会在生成的 Remote(...) 表定义中包含该键,因此基于该定义重新创建的表也能接受多分片 INSERT 查询。 也支持命名集合:

注意事项

  • 该引擎是远程服务器的直通视图:不支持对 Remote 数据库执行 CREATE TABLEDROP TABLEALTER 等 DDL 语句。请直接在远程服务器上管理 schema。
  • 对已配置的远程用户,访问权限由远程服务器强制执行;本地则按数据库及其表上的常规特权进行控制。
  • 用户无权查看的本地分片表会被视为缺失,而非禁止访问。因此,不能通过 Remote 数据库探测用户无权访问的本地数据库中的表名。这既适用于列出表 (SHOW TABLESEXISTS TABLE) ,也适用于解析表 (DESCRIBE TABLESHOW CREATE TABLESELECT) ;此类表也不会通过其所在分片的远程副本提供。只有在本地副本确实没有该表时,才会触发上述回退机制。
  • 列出某个分片的本地副本中存在的数据库的表时,结果还会包含仅存在于该分片远程副本上的表,以确保 SHOW TABLESsystem.tables 与会回退到这些副本的 EXISTS TABLEDESCRIBE TABLESELECT 保持一致。当所有远程副本均未响应时,将原样返回本地副本的表列表,因为它已是可用副本的响应结果。
  • 如果远程服务器不可用,列出其表 (SHOW TABLESsystem.tables) 时会报告连接错误,而不是返回空表列表,这与对同一数据库执行 EXISTS TABLESELECT 时的行为一致。请注意,当此类数据库无法访问时,查询所有数据库的 system.tablesSELECT 也会失败。
  • 一个 Remote 数据库可以指向同一服务器上的另一个 Remote 数据库。列出和描述此类链中的表无需拥有中间数据库的特权——它既不保存自身的数据,也不保存自身的元数据,并且每一跳都会检查调用方对其所代理对象的权限。相比之下,读取和写入数据需要在链的每一跳都拥有 SELECT / INSERT 权限,因为查询实际是在中间数据库的表上执行的,这与在另一个 Distributed 表之上使用 Distributed 表完全相同。上述可见性规则同样适用于该链:中间数据库对调用方隐藏的表,也不会通过外层数据库的远程副本提供。如果本地副本上的中间数据库无法访问其自身的目标,外层分片的本地副本将完全无法响应——就如同该副本本身已宕机——外层数据库会回退到该分片的远程副本。

示例

创建一个指向远程服务器 system 数据库的 Remote 数据库,并从中读取数据:
最后修改于 2026年8月14日