内存占用分析

监控云数据库ClickHouse的内存占用情况是确保系统高效运行和维护数据库性能的重要手段。本文介绍如何使用SQL语句查看云数据库ClickHouse内存占用情况。

示例环境

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

  • 通过控制台:您可以在集群监控页面,获取节点名称。如何进入集群监控页面,请参见查看集群监控信息

  • 通过SQL语句:您可以执行以下语句,获取集群所有节点的名称。

    SELECT * FROM system.clusters;

查看与释放系统内存

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

  • 查看内存占用情况

    查看s-2-r-0节点中各内存占用情况。

    SELECT *,
           formatReadableSize(value)
    FROM clusterAllReplicas('default', system.asynchronous_metrics)
    WHERE (metric like '%Cach%'
      OR metric like '%Mem%')
      AND substring(hostname(), 38, 8) = 's-2-r-0'
    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                  │
    └──────────────────────────────┴─────────────┴───────────────────────────┘

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

    参数

    说明

    MarkCacheBytes

    标记缓存。

    • 记录当前标记缓存所使用的字节数。

    • ClickHouse使用标记缓存来存储数据文件中的索引标记。

    UncompressedCacheBytes

    未压缩缓存。

    • 记录当前未压缩缓存所使用的字节数。

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

  • 释放缓存

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

    重要
    • ClickHouse不支持释放单个节点的缓存,以下指令会以分布式DDL的形式下发,释放集群所有节点的缓存。

    • 释放缓存将对性能产生一定影响,可能导致SQL执行速度变慢,请您根据业务场景谨慎使用。

    释放标记缓存。

    SYSTEM DROP MARK CACHE;

    释放未压缩缓存。

    SYSTEM DROP UNCOMPRESSED CACHE;

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

ClickHouse的Merge操作主要作用是合并数据片段(parts)以提高查询性能和减少存储空间。它是一个定期执行的后台进程,可能会占用大量内存。

了解Merge操作的内存使用情况,可以帮助您识别是否是因Merge操作导致了系统的高内存消耗。您可以通过查看system.merges表数据了解Merge操作的内存占用的具体情况。

  • 查看前Merge占用内存总和

    查看s-2-r-0节点上当前Merge占用内存的总和。

    SELECT
      formatReadableSize (sum(memory_usage))
    FROM
      clusterAllReplicas ('default', system.merges)
    WHERE
      substring(hostname (), 38, 8) = 's-2-r-0';
  • 查看Merge内存占用详情

    查看s-2-r-0节点上,2023-09-17 01:15:002023-09-17 01:30:00内Merge内存占用的详细情况。

    SELECT *
    FROM   clusterAllReplicas ('default', 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 substring(hostname (), 38, 8) = 's-2-r-0'
    ORDER BY peak_memory_usage DESC                             -- 根据peak_memory_usage字段降序排序
    LIMIT 1    

    参数说明

    参数

    说明

    event_type

    事件类型。

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

    SELECT DISTINCT event_type FROM clusterAllReplicas ('default', system.part_log) where substring(hostname (), 38, 8) = 's-2-r-0';

    event_time

    事件发生时间。

查看InMemory datapart的内存占用

ClickHouse中,InMemory datapart通常用于提高查询性能,它的内存占用是ClickHouse的一个重要的性能指标。了解并监控InMemory datapart的内存占用,可以帮助您更好的管理、分配系统资源以及系统优化做有效依据。

system.parts系统表提供了有关表中分区和数据段的信息,您可以通过查看此表,查看InMemory datapart的内存占用详细情况。

查看s-2-r-0节点上被加载到内存中InMemory datapart的大小。

SELECT
  sum(data_uncompressed_bytes)
FROM
  clusterAllReplicas ('default', system.parts)
WHERE
  part_type = 'InMemory'
  AND substring(hostname (), 38, 8) = 's-2-r-0';

查看字典内存占用总量

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

查询s-2-r-0节点上字典内存的占用大小。

SELECT 
  formatReadableSize(sum(bytes_allocated))
FROM clusterAllReplicas('default', system.dictionaries)
WHERE substring(hostname(), 38, 8) = 's-2-r-0';

查看内存表内存占用详情

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

查看Memory、Set和Join引擎表的内存占用情况。

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

查看Query内存占用情况

针对性地分析特定时间段内的Query内存占用情况,有助于识别特定时间段内可能的内存瓶颈或异常使用模式。

ClickHouse中,system.query_log表记录了Query的详细信息。这个表可以帮助你审计和分析数据库的使用情况,了解查询性能,从而解决潜在的问题。

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

查看s-2-r-0节点上正在运行的Query占用内存的总量。

SELECT formatReadableSize(sum(memory_usage)) -- 当前运行query内存占用总量
FROM clusterAllReplicas('default', system.processes)
WHERE substring(hostname(), 38, 8) = 's-2-r-0';

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

查看s-2-r-0节点上正在运行的Query占用内存的详情。

-- 当前运行query内存占用
SELECT initial_query_id,
       elapsed,                               --query耗时
       formatReadableSize(memory_usage),      --内存消耗
       formatReadableSize(peak_memory_usage), --申请内存
       query                                  --query详情
FROM clusterAllReplicas('default', system.processes)
WHERE substring(hostname(), 38, 8) = 's-2-r-0'
ORDER BY peak_memory_usage DESC
LIMIT 10;

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

查看s-2-r-0节点在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('default', system.query_log)
WHERE (event_time >= '2024-01-05 17:00:00')
  AND (event_time <= '2024-01-05 17:40:00')
  AND substring(hostname(), 38, 8) = 's-2-r-0'
ORDER BY memory_usage DESC
LIMIT 10;