在 mysql 5.5 中实现了类似mysql5.7中performance schema 的内存统计功能。

功能

1 展示mysql层内存总大小。

2 展示mysql层内存使用分布情况。

3 展示每个线程使用的内存总大小。

4 展示每个线程使用的内存分布情况。

演示

1 增加状态变量Memory_used 显示mysql层总体使用的内存大小。

mysql> show global status like 'Memory_used';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Memory_used | 30767584 |
+---------------+----------+
1 row in set (0.06 sec)

2 show memory展示mysql层内存使用分布情况。

mysql> show memory;
+----------------------------------------------+-------------+
| name | memory_used |
+----------------------------------------------+-------------+
| libmysql/MYSQL_STMT:mem_root | 0 |
| libmysql/MYSQL_STMT:result::alloc | 0 |
| sql/NET::buff | 16400 |
| sql/Protocol_local::m_rset_root | 0 |
| sql/TABLE | 58992 |
| mysys/my_dir | 0 |
| sql/TABLE::sort.io_cache | 0 |
| sql/THD::main_mem_root | 0 |
| sql/THD::transaction::mem_root | 0 |
| sql/THD::debug_sync_control | 0 |
| sql/debug_sync_control::debug_sync_action | 0 |
| sql/Filesort_info::addonbuf | 0 |
| sql/Filesort_info::record_pointers | 0 |
| sql/SORTPARAM::tmp_buffer | 0 |
| sql/SORT_ADDON_FIELD | 0 |
| sql/user_var_entry | 0 |
| mysys/IO_CACHE | 16400 |
| mysys/TREE | 0 |
| mysys/DYNAMIC_ARRAY | 352136 |
| sql/QUICK_RANGE_SELECT::alloc | 0 |
| sql/QUICK_INDEX_MERGE_SELECT::alloc | 0 |
| sql/QUICK_INDEX_MERGE_SELECT::alloc | 0 |
| sql/QUICK_ROR_INTERSECT_SELECT::alloc | 0 |
| sql/QUICK_ROR_UNION_SELECT::alloc | 0 |
| sql/QUICK_GROUP_MIN_MAX_SELECT::alloc | 0 |
| sql/SQL_SELECT::test_quick_select:alloc | 0 |
| sql/prune_partitions::exec | 0 |
| sql/READ_RECORD::cache | 0 |
| sql/table_mapping::m_mem_root | 0 |
| sql/Locked_tables_list::m_locked_tables_root | 0 |
| sql/Warning_info::m_warn_root | 0 |
| sql/READ_INFO | 0 |
| sql/Prepared_statement::main_mem_root | 0 |
| sql/JOIN_CACHE | 0 |
| sql/TABLE_SHARE::mem_root | 0 |
| sql/LOG_EVENT | 0 |
| sql/QUICK_RANGE_SELECT::multi_range | 0 |
| sql/QUICK_RANGE_SELECT::multi_range_buff | 0 |
| sql/table_def | 0 |
| sql/THD::handler_tables_hash | 0 |
| sql/hash_index_key_buffer | 0 |
| sql/ignore_db | 0 |
| sql/sql_acl_mem | 0 |
| sql/sql_acl_memx | 0 |
| sql/servers | 0 |
| sql/MYSQL_LOCK | 0 |
| sql/KEY_CACHE | 2456 |
| sql/Unique::sort_buffer | 0 |
| sql/Unique::merge_buffer | 0 |
| sql/frm | 0 |
| sql/Query_cache | 0 |
| sql/bision_stack | 0 |
| sql/user_conn | 96 |
| sql/THD::variables | 0 |
| sql/global_system_variables | 144 |
| sql/sercurity_context | 24 |
| sql/sp_head::main_mem_root | 0 |
| sql/sp_head::execute_mem_root | 0 |
| sql/sp_head::call_mem_root | 0 |
+----------------------------------------------+-------------+
59 rows in set (0.00 sec)

3 show processlist增加了Memory_used列展现线程的内存使用(或者 show status like 'Memory_used';)

mysql> show processlist;
+----+------+-----------------+------+---------+------+-------+------------------+-----------+---------------+-----------+-------------+
| Id | User | Host | db | Command | Time | State | Info | Rows_sent | Rows_examined | Rows_read | Memory_used |
+----+------+-----------------+------+---------+------+-------+------------------+-----------+---------------+-----------+-------------+
| 1 | root | 127.0.0.1:45516 | NULL | Query | 0 | NULL | show processlist | 0 | 0 | 1 | 43552 |
+----+------+-----------------+------+---------+------+-------+------------------+-----------+---------------+-----------+-------------+
1 row in set (0.00 sec)

4 新增information_schema.thread_memory_info表展现每个线程内存使用分布

mysql> select * from  information_schema.thread_memory_info;
+-----------+----------------------------------------------+-------------+
| thread_id | type | memory_used |
+-----------+----------------------------------------------+-------------+
| 1 | libmysql/MYSQL_STMT:mem_root | 0 |
| 1 | libmysql/MYSQL_STMT:result::alloc | 0 |
| 1 | sql/NET::buff | 16400 |
| 1 | sql/Protocol_local::m_rset_root | 0 |
| 1 | sql/TABLE | 0 |
| 1 | mysys/my_dir | 0 |
| 1 | sql/TABLE::sort.io_cache | 0 |
| 1 | sql/THD::main_mem_root | 0 |
| 1 | sql/THD::transaction::mem_root | 0 |
| 1 | sql/THD::debug_sync_control | 0 |
| 1 | sql/debug_sync_control::debug_sync_action | 0 |
| 1 | sql/Filesort_info::addonbuf | 0 |
| 1 | sql/Filesort_info::record_pointers | 0 |
| 1 | sql/SORTPARAM::tmp_buffer | 0 |
| 1 | sql/SORT_ADDON_FIELD | 0 |
| 1 | sql/user_var_entry | 0 |
| 1 | mysys/IO_CACHE | 0 |
| 1 | mysys/TREE | 0 |
| 1 | mysys/DYNAMIC_ARRAY | 264 |
| 1 | sql/QUICK_RANGE_SELECT::alloc | 0 |
| 1 | sql/QUICK_INDEX_MERGE_SELECT::alloc | 0 |
| 1 | sql/QUICK_INDEX_MERGE_SELECT::alloc | 0 |
| 1 | sql/QUICK_ROR_INTERSECT_SELECT::alloc | 0 |
| 1 | sql/QUICK_ROR_UNION_SELECT::alloc | 0 |
| 1 | sql/QUICK_GROUP_MIN_MAX_SELECT::alloc | 0 |
| 1 | sql/SQL_SELECT::test_quick_select:alloc | 0 |
| 1 | sql/prune_partitions::exec | 0 |
| 1 | sql/READ_RECORD::cache | 0 |
| 1 | sql/table_mapping::m_mem_root | 0 |
| 1 | sql/Locked_tables_list::m_locked_tables_root | 0 |
| 1 | sql/Warning_info::m_warn_root | 1048 |
| 1 | sql/READ_INFO | 0 |
| 1 | sql/Prepared_statement::main_mem_root | 0 |
| 1 | sql/JOIN_CACHE | 0 |
| 1 | sql/TABLE_SHARE::mem_root | 0 |
| 1 | sql/LOG_EVENT | 0 |
| 1 | sql/QUICK_RANGE_SELECT::multi_range | 0 |
| 1 | sql/QUICK_RANGE_SELECT::multi_range_buff | 0 |
| 1 | sql/table_def | 0 |
| 1 | sql/THD::handler_tables_hash | 0 |
| 1 | sql/hash_index_key_buffer | 0 |
| 1 | sql/ignore_db | 0 |
| 1 | sql/sql_acl_mem | 0 |
| 1 | sql/sql_acl_memx | 0 |
| 1 | sql/servers | 0 |
| 1 | sql/MYSQL_LOCK | 0 |
| 1 | sql/KEY_CACHE | 0 |
| 1 | sql/Unique::sort_buffer | 0 |
| 1 | sql/Unique::merge_buffer | 0 |
| 1 | sql/frm | 0 |
| 1 | sql/Query_cache | 0 |
| 1 | sql/bision_stack | 0 |
| 1 | sql/user_conn | 0 |
| 1 | sql/THD::variables | 0 |
| 1 | sql/global_system_variables | 0 |
| 1 | sql/sercurity_context | 0 |
| 1 | sql/sp_head::main_mem_root | 0 |
| 1 | sql/sp_head::execute_mem_root | 0 |
| 1 | sql/sp_head::call_mem_root | 0 |
+-----------+----------------------------------------------+-------------+
59 rows in set (0.04 sec)

实现

1 mysql层的封装的内存分配与释放的接口如下:

my_malloc, my_realloc,my_free

分别对应底层接口alloc,realloc,free.而calloc在mysql层没有调用过,这里可以忽略掉。

内存统计实现的方法是在内存分配时增加计数统计,在内存释放是减少计数统计。

为了实现内存的分类统计,内存的线程级别的监控。在内存分配时需要额外存储以下3条信息:

1) 内存分配的大小,在内存释放时减少内存计数大小。

2) 当前线程分配的内存是否是线程私有的,以区分公有内存,相对准确统计线程占用的内存大小。

3) 内存的类别,实现的内存的分类统计。

2 内存额外信息的来源

内存分配接口my_malloc, my_realloc都有参数my_flags用于存储一些标记信息。在这里上述的第2和3条信息都存储在my_flags中,在内存分配接口调用时指定。而第1条内存大小,原有接口就有。

1) 标示当前线程分配的内存是否是线程私有的。MY_THREAD_SPECIFIC标记是否是线程私有的线程,MY_THREAD_MOVE 标示内存是否在线程之间移动,只有在my_realloc时发生,目前这种情况还没有出现。

MY_THREAD_SPECIFIC  0x10000

MY_THREAD_MOVE      0x20000

2) 内存的类别,由enum memory_stat_type 定义,从0开始至MST_END。

为了将内存的类别存储在my_flags中,需要将类别值进行移位处理

#define SET_MEM_TYPE(v) ((v) << 18)

3 内存额外信息的存储

内存分配时额外分配MALLOC_PREFIX_SIZE大小的内存,用于存储内存额外信息,并且位于内存头部。

#define MALLOC_PREFIX_SIZE (sizeof(double))

GET_MEM_FLAG从my_flags中取出第2和3条信息。

#define GET_MEM_FLAG(v) ((v) >> 16)

MALLOC_STORE_SIZE将内存额外信息存储在内存头部ALLOC_PREFIX_SIZE大小的内存中。

这样内存释放时可以从内存头部取出这3条信息,来减少相应的内存统计计数。

4 主要接口和数据结构

1)global_status_var.memory_used mysql层占用内存总大小

2)show_mem_array  mysql层内存使用分类大小数组

3) THD::status_var.memory_used 线程占用内存大小

4)THD::mem_used  每个线程使用的内存分类大小数组

5) my_malloc_size_cb_func  增加和减少内存统计计数总入口。

6) mysqld_list_memory: show memory 显示mysql层内存使用分类大小

兼容性

information_schema.processlist 增加了一列MEMORY_USED

新增information_schema.thread_memory_info表

上述变动对升级没有影响。

参考

mysql5.7 http://dev.mysql.com/doc/refman/5.7/en/memory-summary-tables.html

mariadb https://mariadb.atlassian.net/browse/MDEV-4011

【附】

1 目前内存分的类别还不完善,只列了一些主要的分类。

2 虽然内存统计计数使用无锁算法,但还是会影响性能,待评估。

mysql 内存统计的更多相关文章

  1. mysql内存参数整理和条调优以及内存统计

    date:20140530auth:Jin 参考:http://dev.mysql.com/doc/refman/5.5/en/server-status-variables.html#http:// ...

  2. MySQL内存使用查看方式

    使用版本:MySQL 5.7 官方文档 在performance_schema有如下表记录内存使用情况 mysql> show tables like '%memory%summary%'; + ...

  3. MySQL内存计算器

    MySQL如何使用内存? 首先,介绍MySQL使用内存的一些方法: 1. 会话级别的内存消耗(连接私有内存):如sort_buffer_size等,每个会话都会开辟一个sort_buffer_size ...

  4. MySQL的统计信息学习总结

    统计信息概念 MySQL统计信息是指数据库通过采样.统计出来的表.索引的相关信息,例如,表的记录数.聚集索引page个数.字段的Cardinality.....MySQL在生成执行计划时,需要根据索引 ...

  5. 记录一次现网MySQL内存增长超限问题定位过程

    问题现象现网物理机内存近几日内爆涨使用率超过了90%,可用内存从250G,降低到20G以下,报告警.服务器使用情况来看,并没有什么异常.除了QPS缓慢增长外. MySQL内存分配结构 定位这个问题,先 ...

  6. 线上mysql内存持续增长直至内存溢出被killed分析(已解决)

    来新公司前,领导就说了,线上生产环境Mysql库经常会发生日间内存爆掉被killed的情况,结果来到这第一天,第一件事就是要根据线上服务器配置优化配置,同时必须找出现在mysql内存持续增加爆掉的原因 ...

  7. mysql内存消耗分析

    最近有些生产服务器老是mysql内存不停得往上涨,开发人员和维护反馈,用了不少的临时表,问题时常线上发生,测试又一直比较难重现. 经观察mysql内存的os占用趋势,发现从8:40开始,mysql内存 ...

  8. MySQL内存使用分析

    转自: http://www.jb51.net/article/38936.htm 本篇文章是对MySQL内存的使用说明(全局缓存+线程缓存)进行了详细的分析介绍,需要的朋友参考下    首先我们来看 ...

  9. MySQL内存----使用说明全局缓存+线程缓存) 转

    MySQL内存使用说明(全局缓存+线程缓存) 首先我们来看一个公式,MySQL中内存分为全局内存和线程内存两大部分(其实并不全部,只是影响比较大的 部分): per_thread_buffers=(r ...

随机推荐

  1. js便签笔记(14)——用nodejs搭建最简单、轻量化的http server

    1. 引言 前端程序猿主要关注的是页面,你可能根本就用不到.net,java,php等后台语言. 但是你制作出来的网页总要运行.总要测试吧?——那就免不了用到http server.我先前都是用vis ...

  2. INSERT INTO IF EXISTS

    INSERT INTO books (name) SELECT 'MySQL Manual' FROM dual WHERE NOT EXISTS (SELECT id FROM booksWHERE ...

  3. vue-cli 使用better-scroll

    better-scroll  api文档https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/ 一:安装better-scroll 插件 cn ...

  4. GoogLeNetv3 论文研读笔记

    Rethinking the Inception Architecture for Computer Vision 原文链接 摘要 卷积网络是目前最新的计算机视觉解决方案的核心,对于大多数任务而言,虽 ...

  5. Quart2D文字图像绘制

    上一个是绘制简单图形,这一篇学习绘制文字.图像 //获取画布 CGContextRef context=UIGraphicsGetCurrentContext(); //设置边框颜色 CGContex ...

  6. SqlDataAdapter 对datagridview进行增删改(A)

    这种方法主要是双击datagridview单元格,直接进行添加,修改,删除,在实际开发中并不太常用,另一种方法下一次在具体陈述. using System; using System.Collecti ...

  7. 关于 luv_letters

    luv_letters是一枚现高二文化课菜鸡,是一枚临汾一中联赛oier(我太菜了),也是一名Cher. (好像没有好的地方 真名不提跟某个当红女明星一样(正经汉子不女装 话说当初选择竞赛科目的时候( ...

  8. oracle 恢复错误修改数据 寒冬冒冷汗!!

    今天,由于一时疏忽,造成了对正式数据库修改了用户密码的情况.寒冬冒冷汗!!! 立即上网找修改方法,万幸找到,也修改回来,特此在此留个记忆!! create table t_table_new----这 ...

  9. nginx多站点配置

    一.安装nginx https://yq.aliyun.com/articles/101144?spm=5176.10695662.1996646101.searchclickresult.70af9 ...

  10. Dubbox分布式框架

    一:简介:前身是阿里巴巴的一个开源的项目,后来停止维护,由当当网继续维护,它致力于rpc远程的调度方案.是一个服务框架 二:执行原理图: 节点角色说明: · Provider: 暴露服务的服务提供方. ...