美文网首页
第44问:MySQL 的内存消耗, 有哪些不在 performa

第44问:MySQL 的内存消耗, 有哪些不在 performa

作者: 爱可生开源社区 | 来源:发表于2021-09-17 17:36 被阅读0次
    image

    当 MySQL 内存异常上涨, 我们可以通过 performance_schema 观察内存的使用, 我们在实验5中进行过介绍。

    但我们也会发现操作系统统计的 MySQL 内存用量比 performance_schema 统计的 MySQL 内存用量要多。

    那么 MySQL 的内存消耗, 有哪些是不在 performance_schema 统计内的呢?

    本期我们设计实验来观察这个问题

    实验

    我们先安装 google-perftools:

    image

    安装后, 可以找到相关的库:

    image

    宽油起一个数据库:

    image

    记下数据库的启动参数, 并关掉数据库:

    image

    我们在数据库启动命令前, 增加两个环境变量 LD_PRELOAD 和 HEAPPROFILE.

    其中 LD_PRELOAD 指向刚才我们安装的 tcmalloc 库, HEAPPROFILE 是输出文件的路径.

    启动数据库后, 我们看到日志中输出了两个 heap 文件.

    image

    我们在数据库中增加一些压力, 还是用我们熟悉的翻倍法:

    image

    多做点数据:

    image

    观察到输出了更多的 heap 文件:

    image

    下面我们安装 pprof 来解析这些 heap 文件.

    先下载 golang , 此步骤需要挂代理:

    image

    安装 golang :

    image

    安装 pprof :

    image

    用 pprof 解析我们刚才生成的 heap 文件:

    image

    我们让 pprof 生成一个 svg 文件, 我们将 svg 文件放到 Chrome 中打开查看:

    image

    图比较大, 每根线都标记了内存的分配流, 我们用红色箭头标注了三个汇集点 (所有的连线都会流向这三个汇集点中的某一个).

    其中 pfs_malloc 是可以被 performance_schema 跟踪的内存分配, 而其他两个汇集点则不能.

    下面我们将图的一部分放大, 举例来做个大致介绍 (本图中我们用红色箭头增强了原图的连线):

    image

    我们可以看到有16384.53kB是 由 log_allocate_buffer 函数调用 ut_allocator 分配的, 这部分无法被 performance_schema 跟踪到.

    查看一下代码, 得知 log_allocate_buffer 是根据 log_buffer_size 参数申请内存的:

    image

    查看参数, 证实 log_buffer_size 的配置与我们在图中观察到的内存分配一致:

    image

    总结

    本实验中, 我们使用了 tcmalloc 作为 MySQL 的内存分配器, 并使用 tcmalloc 提供的 heap dump 功能, 追踪 MySQL 的内存分配。

    通过内存分配图, 能让我们直观地理解 MySQL 的内存分配:

    我们可以从中观察到 每一部分的内存 是从哪个代码路径进行分配的, 以及哪些内存是 performance_schema 能追踪到的。

    此功能对性能影响不大, 可以在生产上比较平稳的使用, 用于探索生产环境的一些内存分配异常。

    相关文章

      网友评论

          本文标题:第44问:MySQL 的内存消耗, 有哪些不在 performa

          本文链接:https://www.haomeiwen.com/subject/hdksgltx.html