本文描述常见问题及处理办法。

常见问题

如何处理客户端工具连接集群时报错:connect timed out?

您可以采取如下解决方案。
  • 检查网络是否畅通。通过ping命令检查网络是否通畅,通过telnet命令探测集群3306和8123端口是否开放。
  • 检查是否配置了ClickHouse白名单,配置方法请参见设置白名单
  • 检查客户端机器IP是否正确。通常公司办公网内的机器IP为动态IP,用户看到的不是正确的IP地址。通过访问专业IP探查服务确定真实IP,示例请参见whatsmyip

在数据停止写入时,同一个查询语句每次查询的结果不一致,应该如何处理?

问题详细描述:通过select count(*) 查询数据时只有整体数据的大概一半,或者数据一直在跳变。

您可以采取如下解决方案。
  • 检查是否是多节点集群。多节点集群需要创建分布式表,往分布式表里写入数据并查询,每次查询结果一致。否则每次查询到不同分片的数据,结果不一致。如何创建分布式表请参见创建分布式表
  • 检查是否是多副本集群。多副本集群需要建Replicated系列表引擎的表,才能实现副本间数据同步。否则每次查到不同副本,结果不一致。如何创建Replicated系列表引擎的表请参见表引擎

如何处理语法报错:set global on cluster default?

常见原因及解决方案如下。
  • 常见原因1:ClickHouse客户端会进行语法解析,而set global on cluster default是服务端增加的语法。在客户端尚未更新到与服务端对齐的版本时,该语法会被客户端拦截。

    解决方案:
    • 使用JDBC Driver等不会在客户端解析语法的工具,比如DataGrip、DBeaver。
    • 编写JDBC程序来执行该语句。
  • 常见原因2:set global on cluster default key = value; 中value是字符串,但是漏写了引号。

    解决方案:在字符串类型的value两侧加上引号。

购买ClickHouse集群时显示“当前区域资源不足”,应该如何处理?

您可以选择同地域的其他区域购买或提交工单。VPC网络支持相同区域不同可用区之间打通,同区域网络延迟无感知。

购买ClickHouse实例时,推荐选择哪一个版本?

云数据库ClickHouse根据开源社区公开的LTS内核稳定版提供服务,通常在版本推出3个月相对稳定后启动云服务售卖。当前建议购买20.8.7.15 及以上版本。20.8.7.15版本提供冷热数据分层存储增强MaterializedMySQL

单双副本实例各有什么特点?

  • 单副本实例每一个Shard节点无副本节点,无高可用服务保障。数据安全性基于云盘多副本存储,性价比高。
  • 双副本实例每一个Shard节点对应一个副本服务节点,在主节点故障不能提供服务时副本节点可提供容灾服务支持。

如何处理建表后查询表不存在?

常见原因:DDL语句只在一个节点上执行。

解决方案:检查DDL语句是否有on cluster关键字。更多信息,请参见建表语法

如何处理分布式DDL报错:longer than distributed_ddl_task_timeout (=xxx) seconds?

您可以通过使用set global on cluster default distributed_ddl_task_timeout=xxx命令修改默认超时时间,xxx为自定义超时时间,单位为秒。全局参数修改请参见集群参数修改

云数据库ClickHouse和官方版本对比多了哪些功能和特性?

云数据库ClickHouse主要对社区版本进行稳定性Bug修复。同时提供特有的内核特性:
  • 资源队列进行用户角色级别的资源使用优先级配置。
  • 二级索引支持日志明细类点查询场景。

为什么MySQL、HDFS、Kafka等外表无法连通?

目前20.3和20.8版本在创建相关外表时程序内会自动进行验证,如果创建表成功,那说明网络是通的。如果无法创建成功,常见原因如下。
  • 目标端和ClickHouse不在同一个VPC内,网络无法连通。
  • MySQL端存在白名单相关设置,需要在MySQL端添加ClickHouse的白名单。

对于Kafka外表,表创建成功,但查询没有结果。常见原因是Kafka中数据通过表结构给出的字段和格式解析失败,报错信息会给出解析失败的具体位置。

为什么向Kafka外表写入数据后,对应的本地表的数据量不增加?

您可以先对Kafka外表进行select * from的查询,如果查询报错,那可以根据报错信息确定原因(一般是数据解析失败)。如果查询正常返回结果,那需要进一步查看目的表(Kafka外表的具体存储表)和Kafka源表(Kafka外表)的字段是否匹配。如果数据写入失败,那说明字段是匹配不上的。示例语句如下。

insert into <目的表> as select * from <kafka外表>;

如何处理insert into select XXX内存超限报错?

常见原因及解决方案如下。
  • 常见原因1:内存使用率比较高。

    解决方案:调整参数max_insert_threads,减少可能的内存使用量。

  • 常见原因2:当前是通过insert into select把数据从一个ClickHouse集群导入到另外一个集群。

    解决方案:通过导入文件的方式来迁移数据,更多信息请参见从自建ClickHouse迁移上云

为什么OSS外表导入ORC、PARQUET等格式的数据,出现内存报错或OOM挂掉?

常见原因:内存使用率比较高。

您可以采取如下解决方案。
  • 把OSS上的文件拆分为一个一个的小文件,然后再进行导入。
  • 进行内存的升配。如何升配请参见变配和扩缩容

如何处理导入数据报错:too many parts?

ClickHouse每次写入都会生成一个data part,如果每次写入一条或者少量的数据,那会造成ClickHouse内部有大量的data part(会给merge和查询造成很大的负担)。为了防止出现大量的data part,ClickHouse内部做了很多限制,这就是too many parts报错的内在原因。出现该错误,第一要做的事情就是增加写入的批量大小。如果确实没有办法调整批量大小,可以适当的修改参数:max_partitions_per_insert_block

为什么DataX导入速度慢?

常见原因及解决方案如下。
  • 常见原因1:参数设置不合理。ClickHouse适合使用大batch、少数几个并发进行写入。多数情况下batch可以高达几万甚至几十万(取决于您的单行RowSize大小,一般按照每行1KB进行评估,您需要根据实际数据特征进行估算)。

    解决方案:并发数建议不超过10个。您可以调整不同参数进行尝试。

  • 常见原因2:DataWorks独享资源组中,ECS实例的规格低,无法保证高性能。比如独享资源的CPU、Memory太小,导致并发数、网络出口带宽受限;或者是batch设置太大而Memory太小,引起DataWorks进程Java GC等。

    解决方案:您可以通过DataWorks的输出日志对ECS规格大小进行确认。

  • 常见原因3:从数据源中读取慢。

    解决方案:您可以在DataWorks输出日志中搜索totalWaitReaderTime、totalWaitWriterTime,如果发现totalWaitReaderTime明显大于totalWaitWriterTime,则表明主要耗时在读取端,而不是写入端。

  • 常见原因4:使用了公网Endpoint。公网Endpoint的带宽非常有限,无法承载高性能的数据导入导出。

    解决方案:您需要替换为VPC网络的Endpoint。

为什么Hive导入后其数据行数跟ClickHouse对不上 ?

您可以通过如下方式进行排查。
  1. 首先通过系统表query_log来查看导入的过程中是否有报错,如果有报错,那很有可能出现数据丢失的情况。
  2. 确定使用的表引擎是否可以去重,比如使用ReplacingMergeTree,那很可能出现ClickHouse中的Count小于Hive中的情况。
  3. 重新确认Hive中数据行数的正确性,很有可能出现源头的行数确定错误的情况。

为什么Kafka导入后其数据行数跟ClickHouse对不上 ?

您可以通过如下方式进行排查。
  1. 首先通过系统表query_log来查看导入的过程中是否有报错,如果有报错,那很有可能出现数据丢失的情况。
  2. 确定使用的表引擎是否可以去重,比如使用ReplacingMergeTree,那很可能出现ClickHouse中的Count小于Kafka中的情况。
  3. 查看Kafka外表的配置是否有kafka_skip_broken_messages参数的配置,如果有该参数,那可能会跳过解析失败的Kafka消息,导致ClickHouse总的行数是小于Kafka中的。

如何使用Spark、Flink导入数据?

如何从现有ClickHouse导入数据到云数据库ClickHouse?

您可以采取如下解决方案。
  • 通过ClickHouse Client以导出文件的形式进行数据迁移,详情请参见从自建ClickHouse迁移上云
  • 通过Remote函数进行数据的迁移。
    insert into <目的表> select * from remote('<连接串>', '<库>', '<表>', '<username>', '<password>');

为什么数据写入后不可见?

一般原因是分布式表和本地表的表结构不一致造成的。您可以通过查询系统表system.distribution_queue来查看写入分布式表的时候是否发生错误。

如何进行DDL增加列、删除列、修改列操作?

本地表的修改直接执行即可。如果要对分布式表进行修改,需分如下情况进行。
  • 如果没有数据写入,您可以先修改本地表,然后修改分布式表。
  • 如果数据正在写入,您需要区分不同的类型进行操作。
    类型 操作步骤
    增加Nullable的列
    1. 修改本地表。
    2. 修改分布式表。
    修改列的数据类型(类型可以相互转换)
    删除Nullable列
    1. 修改分布式表。
    2. 修改本地表。
    增加非Nullable的列
    1. 停止数据的写入。
    2. 执行SYSTEM FLUSH DISTRIBUTED分布式表。
    3. 修改本地表。
    4. 修改分布式表。
    5. 重新进行数据的写入。
    删除非Nullable的列
    修改列的名称

为什么有时看不到已经创建好的表?

常见原因及解决方案如下。
  • 常见原因1:建表流程存在问题。ClickHouse的分布式集群搭建并没有原生的分布式DDL语义。如果您在自建ClickHouse集群时使用create table创建表,查询虽然返回了成功,但实际这个表只在当前连接的Server上创建了。下次连接重置换一个Server,您就看不到这个表了。

    解决方案:建表时,请使用 create table <table_name> on cluster default语句, on cluster default声明会把这条语句广播给default集群的所有节点进行执行。示例代码如下。
    Create table test on cluster default (a UInt64) Engine = MergeTree() order by tuple();
  • 常见原因2:ReplicatedMergeTree存储表配置有问题。ReplicatedMergeTree表引擎是对应MergeTree表引擎的主备同步增强版,在单副本实例上限定只能创建MergeTree表引擎,在双副本实例上只能创建ReplicatedMergeTree表引擎。

    解决方案:ClickHouse支持表级别的多副本数据同步,目前只有ReplicatedMergeTree有异步同步的能力,在定义ReplicatedMergeTree表引擎时有两个zk路径相关的参数,示例代码如下。
    ReplicatedMergeTree('/clickhouse/tables/{database}/{table}/{shard}', '{replica}')
    代码中出现的参数说明如下。
    参数 说明
    /clickhouse/tables/{database}/{table}/{shard} 分片的唯一Meta路径。
    {replica} 分片下某个副本的Meta路径。
    注意
    • 您只需要按照上面的固定格式定义ReplicatedMergeTree或者直接使用ReplicatedMergeTree(),两个参数都具有默认值填充。
    • 参数路径不可以随意设置,否则会打乱双副本的同步关系。

如何处理查询结果一直抖动时多时少?

常见原因及解决方案如下。
  • 常见原因1:建表流程存在问题。ClickHouse的分布式集群搭建并没有原生的分布式DDL语义。如果您在自建ClickHouse集群时使用create table创建表,查询虽然返回了成功,但实际这个表只在当前连接的Server上创建了。下次连接重置换一个Server,您就看不到这个表了。

    解决方案:
    1. 建表时,请使用create table <table_name> on cluster default语句,on cluster default声明会把这条语句广播给default集群的所有节点进行执行。示例代码如下。
      Create table test on cluster default (a UInt64) Engine = MergeTree() order by tuple();
    2. 在test表上再创建一个分布式表引擎,建表语句如下。
      Create table test_dis on cluster default as test Engine = Distributed(default, default, test, cityHash64(a));
  • 常见原因2:ReplicatedMergeTree存储表配置有问题。ReplicatedMergeTree表引擎是对应MergeTree表引擎的主备同步增强版,在单副本实例上限定只能创建MergeTree表引擎,在双副本实例上只能创建ReplicatedMergeTree表引擎。

    解决方案:ClickHouse支持表级别的多副本数据同步,目前只有ReplicatedMergeTree有异步同步的能力,在定义ReplicatedMergeTree表引擎时有两个zk路径相关的参数,示例代码如下。
    ReplicatedMergeTree('/clickhouse/tables/{database}/{table}/{shard}', '{replica}')
    代码中出现的参数说明如下。
    参数 说明
    /clickhouse/tables/{database}/{table}/{shard} 分片的唯一Meta路径。
    {replica} 分片下某个副本的Meta路径。
    注意
    • 您只需要按照上面的固定格式定义ReplicatedMergeTree或者直接使用ReplicatedMergeTree(),两个参数都具有默认值填充。
    • 参数路径不可以随意设置,否则会打乱双副本的同步关系。

为什么optimize后数据仍未主键合并?

首先为了让数据有正确的主键合并逻辑,需要保证以下两个前提条件。
  • 存储表里的partition by定义字段必须是包含在order by里的,不同分区的数据不会主键合并。
  • 分布式表里定义的Hash算法字段必须是包含在order by里的,不同节点的数据不会主键合并。
optimize常用命令及相关说明如下。
命令 说明
optimize table test; 尝试选取MergeTree的data parts进行合并,有可能没有执行任务就返回。执行了也并不保证全表的记录都完成了主键合并,一般不会使用。
optimize table test partition tuple(); 指定某个分区,选取分区中所有的data parts进行合并,有可能没有执行任务就返回。任务执行后代表某个分区下的数据都合并到了同一个data part,单分区下已经完成主键合并。但是在任务执行期间写入的数据不会参与合并,若是分区下只有一个data part也不会重复执行任务。
说明 对于没有分区键的表,其默认分区就是partition tuple()。
optimize table test final; 对全表所有分区强制进行合并,即使分区下只有一个data part也会进行重新合并,可以用于强制移除TTL过期的记录。任务执行代价最高,但也有可能没有执行合并任务就返回。

对于上面三种命令,您可以设置参数optimize_throw_if_noop通过异常报错感知是否执行任务。

为什么optimize后数据TTL仍未生效?

常见原因及解决方案如下。
  • 常见原因1:数据的TTL淘汰是在主键合并阶段执行的,如果data part迟迟没有进行主键合并,那过期的数据就无法淘汰。

    解决方案:
    • 您可以通过手动optimize final或者optimize 指定分区的方式触发合并任务。
    • 您可以在建表时设置merge_with_ttl_timeout、ttl_only_drop_parts等参数,提高含有过期数据data parts的合并频率。
  • 常见原因2:表的TTL经过修改或者添加,存量的data part里缺少TTL信息或者不正确,这样也可能导致过期数据淘汰不掉。

    解决方案:
    • 您可以通过alter table materialize ttl命令重新生成TTL信息。
    • 您可以通过optimize 分区更新TTL信息。

为什么optimize后更新删除操作没有生效?

云数据库ClickHouse中的更新删除都是异步执行的,目前没有机制可以干预其进度。您可以通过system.mutations系统表查看进度。

为什么optimize任务很慢?

optimize任务非常占用CPU和磁盘吞吐,查询和optimize任务都会相互影响,在机器节点负载压力较大的时候就会表现出optimize很慢问题,目前没有特殊优化方法。

如何处理查询时内存超出限制?

ClickHouse服务端对所有查询线程都配有memory tracker,同一个查询下的所有线程tracker会汇报给一个memory tracker for query,再上层还是memory tracker for total。您可以根据情况采取如下解决方案。
  • 遇到Memory limit (for query)超限报错说明是查询内存占用过多(实例总内存的70%)导致失败,这种情况下您需要垂直升配提高实例内存规模。
  • 遇到Memory limit (for total)超限报错说明是实例总内存使用超限(实例总内存的90%),这种情况下您可以尝试降低查询并发,如果仍然不行则可能是后台异步任务占用了比较大的内存(常常是写入后主键合并任务),您需要垂直升配提高实例内存规模。
说明 如何进行垂直升配请参见 变配和扩缩容

如何查看冷数据大小?

示例代码如下。
select * from system.disks;

如何查询哪些数据在冷存上?

示例代码如下。
select * from system.parts where disk_name = 'cold_disk';

如何移动分区数据到冷存?

示例代码如下。
ALTER TABLE table_name MOVE PARTITION partition_expr TO DISK 'cold_disk';

如何处理查询报并发超限?

默认Server查询最大并发数为100,您可以在控制台上进行修改。修改运行参数值具体操作步骤如下。
  1. 登录云数据库ClickHouse控制台
  2. 集群列表页单击相关集群ID。
  3. 在集群信息页面单击导航栏左侧的参数配置
  4. 修改max_concurrent_queries参数的运行参数值,输入修改值并单击确定修改参数
  5. 单击提交参数
  6. 单击确定

如何处理往表里写入时间戳数据后查询出来的结果与实际数据不同?

SELECT timezone()语句,查看时区是否为当地时区,如果不是修改timezone配置项的值为当地时区。如何修改请参见修改配置项运行参数值

为什么客户端看到的时间结果和时区显示的不一样?

客户端设置了use_client_time_zone,并设定在了错误时区上。

什么查询耗费CPU、MEM高?

您可以在system.query_log系统表里自助查看CPU、MEM高期间的查询日志,里面有每个查询的CPU消耗和内存消耗统计。更多信息请参见system.query_log

水平扩缩容耗时受什么影响?

水平扩容过程涉及数据搬迁,实例里面数据越多搬得越多,耗时时间越长。

扩容期间对实例有什么影响?

为保证扩缩容中数据搬迁后的数据一致性,扩容期间实例处于可读不可写状态。

水平扩缩容升级有什么建议?

水平扩缩容耗时较长,当集群性能不满足时,请优先选择垂直升降配。如何进行垂直升降配,请参见变配和扩缩容

为什么程序无法连接ClickHouse?

常见原因如下。
  • VPC网络、公网 网络环境不对。同一VPC内可用内网连接,不在同一VPC内需开设公网后连接。
  • 白名单未配置。
  • ECS安全组未放开。
  • 公司设置了网络防火墙。

如何处理ClickHouse超时问题?

详情请参见如何处理ClickHouse超时问题

为什么监控中存在数据中断情况?

常见原因如下。
  • 查询触发OOM。
  • 修改配置触发重启。
  • 升降配后的实例重启。

常用系统表有哪些?

常用系统表及作用如下。
名称 作用
system.processes 查询正在执行的SQL。
system.query_log 查询历史执行过的SQL。
system.merges 查询集群上的merge信息。
system.mutations 查询集群上的mutation信息。

如何修改系统级别的参数?是否要重启,有什么影响?

系统级别的参数对应config.xml内的部分配置项,具体修改步骤如下。

  1. 登录云数据库ClickHouse控制台
  2. 集群列表页单击相关集群ID。
  3. 在集群信息页面单击导航栏左侧的参数配置
  4. 修改max_concurrent_queries参数的运行参数值,输入修改值并单击确定修改参数
  5. 单击提交参数
  6. 单击确定

单击确定后,自动重启clickhouse-server,重启会造成约1min闪断。

如何修改用户级别的参数?

用户级别的参数对应users.xml内的部分配置项,你需要执行如下示例语句。
set global on cluster default ${key}=${value};

无特殊说明的参数执行成功后即可生效。

如何修改Quota?

您可以在执行语句的settings里增加,示例代码如下。
settings max_memory_usage = XXX;

每个端口的含义是什么?

端口号 含义
3306 TCP端口。
8123 HTTP端口。

每个Driver对应的端口是什么?

Driver名称 端口号
Java 8123
Python 3306
Go

Go、Python语言对应推荐什么Driver?

详情请参见第三方开发库

有什么BI工具推荐?

QuickBI。

有什么数据查询IDE工具推荐?

DataGrip、DBEaver。

20.8后的版本是否支持平滑升级,不需要迁移数据?

支持。

为什么DDL执行慢,经常卡住?

常见原因:DDL全局的执行是串行执行,复杂查询会导致死锁。

您可以采取如下解决方案。
  • 等待运行结束。
  • 在控制台尝试终止查询。
  • 在云数据库ClickHouse控制台的参数配置页面,对任一参数的参数值进行编辑不修改原来的值,单击提交参数
    说明 如何进行参数值修改请参见 修改参数运行值
  • 如果上述方法仍然无法解决,请提交工单。