You need to enable JavaScript to run this app.
导航
性能诊断之内存占用分析
最近更新时间:2025.03.04 10:31:59首次发布时间:2025.03.04 10:31:59

本文介绍如何通过SQL分析ByteHouse 企业版查询内存占用分析方法。

示例环境

以下示例以 192.18.. 节点为基础环境,在实际使用过程中,请根据您的场景修改对应参数。如果您不知道如何获取节点名称,可以通过以下方式获取。

  • 通过SQL语句:您可以执行以下语句,获取集群所有节点的名称。
SELECT * FROM system.clusters;

查看与释放系统内存

内存的使用情况会直接影响系统的性能和稳定性。通过查看并分析system.asynchronous_metrics表数据,帮助您辨识占用内存多的操作或数据,为您释放内存提供依据。

  • 查看内存占用情况

查看 192.18.. 节点中各内存占用情况。

SELECT *,
       formatReadableSize(value)
FROM clusterAllReplicas('<cluster_name>', system.asynchronous_metrics) 
WHERE (metric like '%Cach%'
  OR metric like '%Mem%')
  AND host() = '192.18.*.*'
ORDER BY metric;
┌─metric───────────────────────┬───value─────┬─formatReadableSize(value)─┐
│ CGroupMemoryTotal            │ 34359738368 │ 32.00 GiB                 │
│ CGroupMemoryUsed             │  4641132544 │ 4.32 GiB                  │
│ CompiledExpressionCacheBytes │       16384 │ 16.00 KiB                 │
│ CompiledExpressionCacheCount │           2 │ 2.00 B                    │
│ FilesystemCacheBytes         │           0 │ 0.00 B                    │
│ FilesystemCacheFiles         │           0 │ 0.00 B                    │
│ HashTableStatsCacheEntries   │           8 │ 8.00 B                    │
│ HashTableStatsCacheHits      │      528011 │ 515.64 KiB                │
│ HashTableStatsCacheMisses    │          15 │ 15.00 B                   │
│ IndexMarkCacheBytes          │           0 │ 0.00 B                    │
│ IndexMarkCacheFiles          │           0 │ 0.00 B                    │
│ IndexUncompressedCacheBytes  │           0 │ 0.00 B                    │
│ IndexUncompressedCacheCells  │           0 │ 0.00 B                    │
│ MMapCacheCells               │           0 │ 0.00 B                    │
│ MarkCacheBytes               │        7968 │ 7.78 KiB                  │
│ MarkCacheFiles               │          24 │ 24.00 B                   │
│ MemoryCode                   │   390758400 │ 372.66 MiB                │
│ MemoryDataAndStack           │ 14373392384 │ 13.39 GiB                 │
│ MemoryResident               │   761221120 │ 725.96 MiB                │
│ MemoryShared                 │   377688064 │ 360.19 MiB                │
│ MemoryVirtual                │ 18072178688 │ 16.83 GiB                 │
│ OSMemoryAvailable            │ 32480075776 │ 30.25 GiB                 │
│ OSMemoryCached               │  4239949824 │ 3.95 GiB                  │
│ OSMemoryFreePlusCached       │ 32480169984 │ 30.25 GiB                 │
│ OSMemoryFreeWithoutCached    │ 28240220160 │ 26.30 GiB                 │
│ OSMemoryTotal                │ 32881352704 │ 30.62 GiB                 │
│ QueryCacheBytes              │           0 │ 0.00 B                    │
│ QueryCacheEntries            │           0 │ 0.00 B                    │
│ UncompressedCacheBytes       │      349487 │ 341.30 KiB                │
│ UncompressedCacheCells       │         114 │ 114.00 B                  │
└──────────────────────────────┴─────────────┴───────────────────────────┘

分析内存占用时重点关注以下参数。

参数

说明

cluster_name

集群名称

MarkCacheBytes

标记缓存。

  • 记录当前标记缓存所使用的字节数。
  • ByteHouse使用标记缓存来存储数据文件中的索引标记。

UncompressedCacheBytes

未压缩缓存。

  • 记录当前未压缩缓存所使用的字节数。
  • ByteHouse的数据在存储过程中通常采用压缩技术,以节省存储空间并提高I/O效率。未压缩缓存用于存储从磁盘读取并解压的数据块,这样在下一次需要相同的数据块时,可以直接从内存中获取,不必重新从磁盘读取和解压,从而进一步提升了查询性能。

释放缓存

经分析内存占用情况后,如果您需要释放缓存,可以通过以下SQL语句释放缓存。

注意

ByteHouse 支持释放单个节点的缓存,你可是在查询页面选择全节点或选择一个节点模式执行如下指令,释放集群单节点或全部节点的缓存。释放缓存将对性能产生一定影响,可能导致SQL执行速度变慢,请您根据业务场景谨慎使用。

释放标记缓存。

SYSTEM DROP MARK CACHE;

释放未压缩缓存。

SYSTEM DROP UNCOMPRESSED CACHE;

查看Merge过程的内存占用情况

ByteHouse的Merge操作主要作用是合并数据片段(parts)以提高查询性能和减少存储空间。它是一个定期执行的后台进程,可能会占用大量内存。
了解Merge操作的内存使用情况,可以帮助您识别是否是因Merge操作导致了系统的高内存消耗。您可以通过查看system.merges表数据了解Merge操作的内存占用的具体情况。

查看前Merge占用内存总和

查看192.18.*.*节点上当前Merge占用内存的总和。

SELECT
  formatReadableSize (sum(memory_usage))
FROM
  clusterAllReplicas ('<cluster_name>', system.merges)
WHERE
  host() = '192.18.*.*';

查看Merge内存占用详情

查看192.18.*.*节点上,2023-09-17 01:15:002023-09-17 01:30:00内Merge内存占用的详细情况。

SELECT *
FROM   clusterAllReplicas ('<cluster_name>', system.part_log)      -- 从system.part_log系统表中选择记录
WHERE (event_type = 'MergeParts')                           -- 查找event_type为'MergeParts'的事件
  AND (event_time >= '2023-09-17 01:15:00')                 -- 事件时间大于或等于2023年9月17日01:15:00
  AND (event_time <= '2023-09-17 01:30:00')                 -- 且事件时间小于或等于2023年9月17日01:30:00
  AND host() = '192.18.*.*'
ORDER BY peak_memory_usage DESC                             -- 根据peak_memory_usage字段降序排序
LIMIT 1    
  • 参数说明

参数

说明

cluster_name

集群名称

event_type

事件类型。
通过不同事件类型来获取相对应的事件信息。您可以通过以下SQL语句获取ClickHouse中的事件类型。

SELECT DISTINCT event_type FROM clusterAllReplicas ('<cluster_name>', system.part_log) where host() = '192.18.*.*';

event_time

事件发生时间。

查看InMemory datapart的内存占用

在ByteHouse中,InMemory datapart通常用于提高查询性能,它的内存占用是ByteHouse的一个重要的性能指标。了解并监控InMemory datapart的内存占用,可以帮助您更好的管理、分配系统资源以及系统优化做有效依据。
system.parts系统表提供了有关表中分区和数据段的信息,您可以通过查看此表,查看InMemory datapart的内存占用详细情况。
查看192.18.*.*节点上被加载到内存中InMemory datapart的大小。

SELECT
  sum(data_uncompressed_bytes)
FROM
  clusterAllReplicas ('<cluster_name>', system.parts)
WHERE
  part_type = 'InMemory'
  AND host() = '192.18.*.*';

查看字典内存占用总量

在ByteHouse中,字典是一种重要的数据结构,用于优化查询性能,特别是在处理维度表和外键时。通过查看system.dictionaries表数据,能够帮助您了解各个字典的加载状态和内存占用情况。
查询192.18.*.*节点上字典内存的占用大小。

SELECT 
  formatReadableSize(sum(bytes_allocated))
FROM clusterAllReplicas('<cluster_name>', system.dictionaries)
WHERE host() = '192.18.*.*';

BitEngine 字典内存占用

在ByteHouse 中,有一种特殊的数据类型BitMap64,底层使用BitEngine 字典,解决bitmap存储的元素过于稀疏。可通过查看system.bitengine表数据,能够帮助内存占用情况。

SELECT
    database,
    table,
    arraySum(encoded_columns_size) as dict_size,
    formatReadableSize(ceil(dict_size / 10000000.0) * 600 * 1024 * 1024) as memory_usage
FROM
    clusterAllReplicas('<cluster_name>',system.bitengine)
WHERE host() = '192.18.*.*';
ORDER BY dict_size DES;

查看内存表内存占用详情

在ByteHouse中,Memory、Set、Join等引擎表的内存使用是有限的,监控这些指标可以帮助您预防因内存溢出导致的错误或异常行为。
查看Memory、Set和Join引擎表的内存占用情况。

SELECT
   `database`,
    name,
    formatReadableSize(total_bytes)
FROM clusterAllReplicas('<cluster_name>',system.tables)
WHERE engine IN ('Memory','Set','Join');

查看Query内存占用情况

针对性地分析特定时间段内的Query内存占用情况,有助于识别特定时间段内可能的内存瓶颈或异常使用模式。
在ByteHouse中,system.query_log表记录了Query的详细信息。这个表可以帮助你审计和分析数据库的使用情况,了解查询性能,从而解决潜在的问题。

查看当前运行Query的内存占用总量

查看192.18.*.*节点上正在运行的Query占用内存的总量。

SELECT formatReadableSize(sum(memory_usage)) -- 当前运行query内存占用总量
FROM clusterAllReplicas('<cluster_name>', system.processes)
WHERE host() = '192.18.*.*';

查看当前运行Query的内存占用详情

查看192.18.*.*节点上正在运行的Query占用内存的详情。

-- 当前运行query内存占用
SELECT initial_query_id,
       elapsed,                               --query耗时
       formatReadableSize(memory_usage),      --内存消耗
       formatReadableSize(peak_memory_usage), --申请内存
       query                                  --query详情
FROM clusterAllReplicas('<cluster_name>', system.processes)
WHERE host() = '192.18.*.*'
ORDER BY peak_memory_usage DESC
LIMIT 10;

查看历史Query的内存占用详情

查看192.18.*.*节点在2024-01-05 17:00:002024-01-05 17:40:00时间段内,运行的Query占用内存的详情。

-- 历史query内存占用
SELECT type,
       event_time,
       initial_query_id,
       formatReadableSize(memory_usage),
       query
FROM clusterAllReplicas('<cluster_name>', system.query_log)
WHERE (event_time >= '2024-01-05 17:00:00')
  AND (event_time <= '2024-01-05 17:40:00')
  AND host() = '192.18.*.*'
ORDER BY memory_usage DESC
LIMIT 10;