集群环境删除表
sql
drop table db_name.table_name on cluster default_cluster sync;
集群环境删除字段
sql
alter table db_name.table_name on cluster default_cluster drop column `remark`;
删除数据,分异步删除和同步删除
delete,update操作对于ck来说是非常重得操作,ck集群容易卡住。
sql
按分区进行删除,该操作异步删除
ALTER TABLE db_name.table_name DROP PARTITION ('37','2021-12-09')
按条件进行删除,该操作同步删除,进行该操作相当于要对表数据重新进行分区处理。
delete操作很慢,可以查询出符合条件的主键id,根据主键id来delete数据。
ALTER TABLE db_name.table_name DELETE WHERE id = 1 and name='小米'
多字段分区或者设置主键得顺序
主键顺序得设置可大幅提高表得查询效率,例如符合主键a,b。如果在业务过程重b作为条件使用较多,那么则在建表遵循最左原则,
ORDER BY (b, a)
clickhouse同步插入数据
sql
向分布式表插入同步数据
set insert_distributed_sync = 1;
插入过程中不设置超时时间
set distributed_ddl_task_timeout = -1;
如果有多个副本,前提是知道集群中有两个副本,只有所有副本同步后采才表名插入成功
set insert_quorum =2;
插入过程中不设置超时时间
set insert_quorum_timeout=3600000;
磁盘清理
sql
查看表占用数据得大小
SELECT
database,
table,
formatReadableSize(sum(bytes_on_disk)) AS disk_space,
sum(bytes_on_disk) AS bytes_on_disk1
FROM system.parts
WHERE (table NOT LIKE '%1111%') AND (table NOT LIKE '%1111%')
GROUP BY
database,
table
ORDER BY bytes_on_disk1 DESC;
SELECT
table,
formatReadableSize(sum(bytes_on_disk)) AS disk_space,
sum(bytes_on_disk) AS bytes_on_disk1
FROM system.parts
WHERE database = 'app'
GROUP BY
table
ORDER BY bytes_on_disk1 DESC limit 10;
truncate table system.query_thread_log;
alter table system.query_thread_log modify TTL event_date + INTERVAL 10 day;
检查数据大小
SELECT table,
formatReadableSize(sum(data_compressed_bytes)) AS tc,
formatReadableSize(sum(data_uncompressed_bytes)) AS tu,
round((sum(data_compressed_bytes) / sum(data_uncompressed_bytes)) * 100,2) AS ratio
FROM system.columns
WHERE database = 'app'
GROUP BY table
ORDER BY sum(data_compressed_bytes) desc limit 10;
检查列的大小
SELECT
column,
any(type),
sum(column_data_compressed_bytes) AS compressed,
sum(column_data_uncompressed_bytes) AS uncompressed,
sum(rows)
FROM system.parts_columns
WHERE (database = 'app') AND (table = 'app_scrm_yk_member_asset_structure_da_1111') AND active
GROUP BY column
ORDER BY column DESC
LIMIT 10;
clickhouse问题分析
慢查
sql
1、字段信息
query_kind:sql执行类型
select:查询
insert:插入
type:执行查询时发生的事件类型
QueryStart,查询执行成功开始
QueryFinish,查询执行成功结束
ExceptionBeforeStart,在开始执行查询之前发生异常
ExceptionWhileProcessing,查询执行期间的异常
event_data:查询开始日期
event_time:查询开始时间
query_start_time:查询开始时间
query_duration_ms:查询执行持续时间
read_rows:读取行数
read_bytes:读取字节数
written_rows:对于插入查询,写入的行数,对于其他查询,值为0
written_bytes:对于插入查询,写入的字节数,对于其他查询,值为0
result_rows:结果中的行数
result_btes:结果中的字节数
memory_usage:查询消耗的内存
query:查询字符串
exception:异常信息
address:发起查询的IP地址
port:发起查询的客户端端口
2、查询一段时间内表写入数据量
SELECT
sum(if(type = 1, 1, 0)) AS cnt,
sum(if(type = 2, written_bytes, 0)) AS written_bytes,
sum(if(type = 2, written_rows, 0)) AS written_rows
FROM clusterAllReplicas('default_cluster', 'system.query_log')
WHERE ((tables[1]) = 'app_eap_event_register_member_de_153579')
AND (query_kind = 'Insert') AND (event_date = '2023-08-20')
AND (event_time >= '2023-08-20 21:00:00')
LIMIT 10;
3、查询一段时间内表写入明细
SELECT
written_bytes,
written_rows,
event_time
FROM clusterAllReplicas('default_cluster', 'system.query_log')
WHERE ((tables[1]) = 'app_eap_event_register_member_de_153579')
AND (query_kind = 'Insert') AND (event_date = '2023-08-20')
AND (event_time >= '2023-08-20 21:00:00')
LIMIT 10;
4、查询一段时间内表查询明细(根据查询耗时倒叙)
SELECT
query_kind,
type,
event_date,
event_time,
read_rows,
read_bytes,
result_rows,
result_bytes,
query_duration_ms,
query
FROM clusterAllReplicas('default_cluster', 'system.query_log') AS t
WHERE (query_kind = 'Select') AND (event_date = '2023-08-20')
AND (event_time >= '2023-08-20 21:00:00')
ORDER BY query_duration_ms DESC
LIMIT 10;
5、查询一段时间内表查询明细(根据结果集倒叙)
SELECT
query_kind,
type,
event_date,
event_time,
read_rows,
read_bytes,
result_rows,
result_btes,
query_duration_ms,
query
FROM clusterAllReplicas('default_cluster', 'system.query_log') AS t
WHERE (query_kind = 'Select') AND (event_date = '2023-09-26')
AND (event_time >= '2023-09-26 16:00:00')
ORDER BY result_rows DESC
LIMIT 10;
6、查询一段时间内表查询异常
SELECT
hostName() AS hostName,
event_time,
query,
query_id,
exception_code,
exception,
stack_trace
FROM clusterAllReplicas('default_cluster', 'system.query_log') AS t
WHERE (query_kind = 'Select') AND (event_date = '2023-09-26')
AND (event_time >= '2023-09-26 16:00:00') AND (type != 'QueryStart')
AND (type != 'QueryFinish')
LIMIT 10;
7、查询正在执行的进程
select elapsed,query,query_id from system.processes order by elapsed desc
#KILL QUERY where query_id='query_id';
#将"query_id"替换为要停止的查询的ID
8、查询待执行的merge
SELECT *
FROM system.mutations
WHERE is_done = 0
#KILL MUTATION WHERE database = 'default' AND table = 'table'
可以终止
耗cpu
sql
SELECT
any(query_duration_ms),
any(query_start_time),
any(query),
sum(`ProfileEvents.Values`[indexOf(`ProfileEvents.Names`, 'UserTimeMicroseconds')]) AS userCPU
FROM system.query_log
WHERE (type = 2) AND (event_date >= today())
GROUP BY normalizedQueryHash(query)
ORDER BY userCPU DESC
LIMIT 10;
#normalizedQueryHash(query) 返回64位的hashID值 不包含相似查询的字面量
查询某个时间内某种查询的数量
sql
#将sql聚合
select normalizedQueryHash(query),count(1) as count
from clusterAllReplicas('default_cluster', 'system.query_log')
where query_start_time> '2024-03-27 06:00:00' and query_start_time< '2024-03-27 06:55:00'
GROUP BY normalizedQueryHash(query)
order by count desc
limit 10;
#通过上面得到的SQL hash值查询具体的SQL语句
select query
from clusterAllReplicas('default_cluster', 'system.query_log')
where query_start_time> '2024-03-27 06:30:00' and query_start_time< '2024-03-27 06:55:00'
and normalizedQueryHash(query)=13758478862166244964
limit 1;
#或者将以上2句合成1句,但是返回信息太杂乱
select any(query),normalizedQueryHash(query),count(1) as count
from clusterAllReplicas('default_cluster', 'system.query_log')
where query_start_time> '2024-03-27 06:00:00' and query_start_time< '2024-03-27 06:55:00'
GROUP BY normalizedQueryHash(query)
order by count desc
limit 10;
参数优化
clickhouse 设置允许使用窗口函数 set allow_experimental_window_functions = 1
cat /etc/clickhouse-server/users.d/allow_experimental_window_functions.xml
xml
<?xml version="1.0"?>
<yandex>
<profiles>
<default>
<allow_experimental_window_functions>1</allow_experimental_window_functions>
</default>
</profiles>
</yandex>
ClickHouse 进行复杂查询时,包含多个 left join 和 group by,会报错:超出内存限制。
sql
SET max_memory_usage = 128000000000; #128G,
如果没有那么多的内存可用,ClickHouse 可以通过设置这个 "溢出" 数据到磁盘:
set max_bytes_before_external_group_by=20000000000; #20G
set max_memory_usage=40000000000; #40G
将 max_memory_usage 设置为 max_bytes_before_external_group_by 大小的两倍。
如果发现还是报内存不够或者服务器直接崩溃,设置 partial_merge_join = 1,但是运行速度会很慢。
重要系统表
sql
执行的sql都可在改表查到
system.query_log
mergeTree表执行的update和delete
done 1 完成 0 未完成
system.mutations
select * from system.mutations where is_done != '1' order by create_time limit 10;
分布式CREATE, DROP, ALTER, RENAME语句
system.distributed_ddl_queue
select entry, cluster, query, host_address, port, status,query_start_time from system.distributed_ddl_queue
where status != '1' order by query_start_time limit 10;
system.processes
正在执行的进程
常见问题解决
ck集群断连
sql
阿里云
原因:在2024-01-26 17:40左右,业务高峰期,CPU高达95%(短时间内的CPU高是正常现象),宿主机被打hang住了,阿里云的工程师收到后台告警,第一时间将宿主机重启了。影响时间为:17.45到17.52。
解决:资源打满之后,管控侧的安全策略驱逐了这个节点。这个策略后续后端会优化,后续会有更合理的策略来均衡资源使用。-阿里云侧
在2024-02-19 16:00-16:10左右,又出现底层主机 hang 住了 重启后恢复了
1、对于宿主机问题,这边核实为:ECS 都是单租户模式的,上面只会部署一个用户的实例,负载高一定是实例业务导致的;所以目前迁移底层实例也无法规避这个问题
2、对于优化管控这个问题,因为涉及到底层探活机制的改动,预计3.31之前优化完成。
2024-02-21 14:00 ck集群某个节点发生重启,导致部分查询失败
正常情况如果 SQL需要的内存小于实例可分配的内存,会直接报错不执行,不会导致OOM;
OOM导致重启属于特殊情况:
当内存水位较高(达到了百分之90以上了,持续时间2分左右)
执行的sql的预估内存可能和实际的执行消耗不一样,这可能会由一些缓存或者其他的原因导致,
这个时候也可能出现预估没有超限但是在执行过程中超限的情况。这个时候这个sql在进行内存预估加载mark文件的时候就直接OOM了,
相当于还没预估出来就OOM了。其实这就是所谓的没来得及Kill。
为何避免这种情况,需保证内存水位保持正常状态
2024-05-07
内存高水位,导致集群oom重启了,加一下内存使用率的告警,内存使用率在80%以上就值得注意了,因为操作系统大概会占百分之十几的内存,所以建议您在内存使用率85%设置告警
下面的SQL来查看一下问题时间的大SQL;
select hostname(), formatReadableSize(memory_usage), query_start_time, event_time, query from clusterAllReplicas(default, system.query_log) where event_time >= '2024-05-06 15:25:00' and event_time <= '2024-05-06 15:35:00' order by memory_usage desc LIMIT 100
下面这个SQL可以看问题时间没有执行完成的SQL
WITH '2024-05-06 15:25:00' AS start_time, '2024-05-06 15:35:00' AS end_time SELECT query_id, query FROM system.query_log WHERE event_time BETWEEN start_time AND end_time AND type = 'QueryStart' AND query_id NOT IN ( SELECT query_id FROM system.query_log WHERE event_time BETWEEN start_time AND end_time AND type = 'QueryFinish' )
因为有几条DDL执行太慢卡住了;跟optimize没有直接关系,不过optimize本身也是比较消耗性能的,建议不要下发得过于频繁
华为云
宿主机 认为ck的CPU占用太多 ,把ck kill掉了
关注参数
show settings like 'max_server_memory_usage_to_ram_ratio'; 调低
DDL语句卡住不执行
sql
如执行alter delete/update 卡住,卡住会导致后续的所有ddl语句执行不了,卡住第一时间需要解决,否则会影响夜里的任务执行
解决办法:将卡住的zk上队列节点删除掉,再重启ck集群
1、进入zk
2、查到卡住的zk队列节点
ls /clickhouse/distributed_ddl
一般最后一个队列节点就是卡住的队列节点,可以查看该队列节点内容
如get /clickhouse/distributed_ddl/query-0000230088
active finished
或者通过查询system.query_log 可以找到执行卡住的sql的query_id
3、删除卡住的zk队列节点
deleteall /clickhouse/distributed_ddl/query-0000230088
4、重启ck集群,滚动重启的方式,不影响现有业务