千家信息网

有哪些数据库内存知识点

发表于:2024-09-21 作者:千家信息网编辑
千家信息网最后更新 2024年09月21日,本篇内容介绍了"有哪些数据库内存知识点"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、如何看懂内存
千家信息网最后更新 2024年09月21日有哪些数据库内存知识点

本篇内容介绍了"有哪些数据库内存知识点"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、如何看懂内存指标

遇到内存问题,可以先通过free、vmstat、top等命令,进行检查。free命令,可以获取系统内存的总体使用情况;vmstat命令,可以实时观察内存的变化情况;top命令,可以进行排序,获取内存占用大的进程。这里简单介绍一下free命令输出(以CentOS 7为例):

total        used        free      shared  buff/cache   available Mem:        8008704     5234876      157920         640     2615908     2467292 Swap:          2047           0        2047

第一行是内存数据

1. total:内存总大小,对应于/proc/meminfo的MemTotal

2. used:已使用的内存大小,对应于/proc/meminfo的(MemTotal - MemFree - Buffers - Cached - Slab)

3. free:未使用的内存大小,对应于/proc/meminfo的MemFree

4. buff/cache:已使用的缓存大小,对应于/proc/meminfo的Buffers+Cached

5. available:可供使用的内存大小,这是一个预估值,对应于/proc/meminfo的MemAvailable

第二行是交换分区数据

1. total:交换分区总大小,对应于/proc/meminfo的SwapTotal

2. used:已使用的交换分区,对应于/proc/meminfo的(SwapTotal - SwapFree)

3. free:未使用的的内存大小,对应于/proc/meminfo的SwapFree

这里值得注意的是,Linux操作系统会最大限度利用内存,空闲内存free少,不代表系统内存不够用了。个人建议,一方面需要观察内存增长的整体趋势是否逐渐趋于平稳、以及used和buff/cache的变化情况;另一方面需要观察是否频繁使用到交换分区swap,当然了,这里要避免NUMA和swapiness设置不正确带来的干扰。

二、MySQL如何使用内存

在MySQL中,内存占用主要包括以下几部分,全局共享的内存、线程独占的内存、内存分配器占用的内存,具体如下:

全局共享

1. innodb_buffer_pool_size:InnoDB缓冲池的大小

2. innodb_additional_mem_pool_size:InnoDB存放数据字典和其他内部数据结构的内存大小,5.7已被移除

3. innodb_log_buffer_size:InnoDB日志缓冲的大小

4. key_buffer_size:MyISAM缓存索引块的内存大小

5. query_cache_size:查询缓冲的大小,8.0已被移除

线程独占

1. thread_stack:每个线程分配的堆栈大小

2. sort_buffer_size:排序缓冲的大小

3. join_buffer_size:连接缓冲的大小

4. read_buffer_size:MyISAM顺序读缓冲的大小

5. read_rnd_buffer_size:MyISAM随机读缓冲的大小、MRR缓冲的大小

6. tmp_table_size/max_heap_table_size:内存临时表的大小

7. binlog_cache_size:二进制日志缓冲的大小

内存分配器

在MySQL中,buffer pool的内存,是通过mmap()方式直接向操作系统申请分配;除此之外,大多数的内存管理,都需要经过内存分配器。为了实现更高效的内存管理,避免频繁的内存分配与回收,内存分配器会长时间占用大量内存,以供内部重复使用。关于内存分配器的选择,推荐使用jemalloc,可以有效解决内存碎片与提升整体性能。

因此,MySQL占用内存高的原因可能包括:innodb_buffer_pool_size设置过大、连接数/并发数过高、大量排序操作、内存分配器占用、以及MySQL Bug等等。一般来说,在MySQL整个运行周期内,刚启动时内存上涨会比较快,运行一段时间后会逐渐趋于平稳,这种情况是不需要过多关注的;如果在稳定运行后,出现内存突增、内存持续增长不释放的情况,那就需要我们进一步分析是什么原因造成的。

三、到底是谁占用了内存

在绝大多数情况下,我们是不需要花费过多精力,去关注MySQL内存使用情况的; 但是,也不能排除确实存在内存占用异常的情况,这个时候我们应该如何去进行深入排查呢? 其实,MySQL官方就提供了强大的实时监控工具——performance_schema库下的监控内存表,通过这个工具,我们可以很清晰地观察到MySQL内存到底是被谁占用了、分别占用了多少。

开启内存监控

实例启动时开启

我们可以选择,在实例启动时,开启内存监控采集器,具体方法如下:

vi my.cnf performance-schema-instrument='memory/%=ON'

禁用方法如下:

vi my.cnf performance-schema-instrument='memory/%=OFF'

实例运行时开启

我们也可以选择 ,在实 例运 行时,动态开启内存监控采集器,具体方法如下:

mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'memory/%';

禁用方法如下:

mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'NO' WHERE NAME LIKE 'memory/%';

因为采集器的实现原理,是在内存进行分配/回收时,更新相对应内存监控表的数据;换句话说,就是采集器只能监控到开启之后的内存使用情况;而MySQL很大一部分内存都是在实例启动时就预先分配的,因此要想准确监控实例的内存使用率,需要在实例启动时就开启内存采集器。

内存监控表

在performance_schema库下,提供多个维度的内存监控表,具体如下:

memory_summary_by_account_by_event_name: 账号纬度的内存监控表

memory_summary_by_host_by_event_name: 主机纬度的内存监控表

memory_summary_by_thread_by_event_name: 线程维度的内存监控表

memory_summary_by_user_by_event_name: 用户纬度的内存监控表

memory_summary_global_by_event_name: 全局纬度的内存监控表

内存监控表均包括以下关键字段:

COUNT_ALLOC: 内存分配次数

C OUNT_FREE: 内存回收次数

S UM_NUMBER_OF_BYTES_ALLOC: 内存分配大小

SUM_NUMBER_OF_BYTES_FREE: 内存回收大小

CURRENT_COUNT_USED: 当前分配的内存,通过COUNT_ALLOC-COUNT_FREE计算得到

CURRENT_NUMBER_OF_BYTES_USED: 当前分配的内存大小,通过SUM_NUMBER_OF_BYTES_ALLOC-SUM_NUMBER_OF_BYTES_FREE计算得到

LOW_COUNT_USED: CURRENT_COUNT_USED的最小值

HIGH_COUNT_USED: CURRENT_COUNT_USED的最大值

LOW_NUMBER_OF_BYTES_USED: CURRENT_NUMBER_OF_BYTES_USED的最小值

HIGH_NUMBER_OF_BYTES_USED: CURRENT_NUMBER_OF_BYTES_USED的最大值

接下来,让我们看一个正常运行实例的内存使用情况,具体如下:

mysql> select USER,HOST,EVENT_NAME,COUNT_ALLOC,COUNT_FREE,CURRENT_COUNT_USED,SUM_NUMBER_OF_BYTES_ALLOC,SUM_NUMBER_OF_BYTES_FREE,CURRENT_NUMBER_OF_BYTES_USED from performance_schema.memory_summary_by_account_by_event_name order by CURRENT_NUMBER_OF_BYTES_USED desc limit 10; +------+-----------+----------------------------+-------------+------------+--------------------+---------------------------+--------------------------+------------------------------+ | USER | HOST      | EVENT_NAME                 | COUNT_ALLOC | COUNT_FREE | CURRENT_COUNT_USED | SUM_NUMBER_OF_BYTES_ALLOC | SUM_NUMBER_OF_BYTES_FREE | CURRENT_NUMBER_OF_BYTES_USED | +------+-----------+----------------------------+-------------+------------+--------------------+---------------------------+--------------------------+------------------------------+ | NULL | NULL      | memory/innodb/buf_buf_pool |          32 |          0 |                 32 |                4500488192 |                        0 |                   4500488192 | | NULL | NULL      | memory/innodb/os0event     |     1573559 |          0 |            1573559 |                 214004024 |                        0 |                    214004024 | | NULL | NULL      | memory/innodb/hash0hash    |          82 |          6 |                 76 |                 397976480 |                227067024 |                    170909456 | | NULL | NULL      | memory/innodb/log0log      |          10 |          0 |                 10 |                  33565840 |                        0 |                     33565840 | | root | localhost | memory/innodb/std          |     3650638 |    3043111 |             607527 |                 160778066 |                141334898 |                     19443168 | | NULL | NULL      | memory/mysys/KEY_CACHE     |           3 |          0 |                  3 |                   8390768 |                        0 |                      8390768 | | NULL | NULL      | memory/innodb/ut0pool      |           2 |          0 |                  2 |                   4194480 |                        0 |                      4194480 | | NULL | NULL      | memory/innodb/sync0arr     |           3 |          0 |                  3 |                   2506184 |                        0 |                      2506184 | | NULL | NULL      | memory/innodb/lock0lock    |          33 |          0 |                 33 |                   2245040 |                        0 |                      2245040 | | root | localhost | memory/innodb/mem0mem      |     9897784 |    9896793 |                991 |                8845389160 |               8843147749 |                      2241411 | +------+-----------+----------------------------+-------------+------------+--------------------+---------------------------+--------------------------+------------------------------+ 10 rows in set (0.01 sec)

再看一个Bug #86821的场景,buffer pool占用最大内存正常,但是存储过程占用3GB就比较异常了,存在内存泄漏的风险;由此可知,通过内存监控表,我们可以快速定位内存异常占用问题。

mysql> select event_name, current_alloc, high_alloc from memory_global_by_current_bytes where current_count > 0; +--------------------------------------------------------------------------------+---------------+-------------+ | event_name                                                                     | current_alloc | high_alloc  | +--------------------------------------------------------------------------------+---------------+-------------+ | memory/innodb/buf_buf_pool                                                     | 7.29 GiB      | 7.29 GiB    | | memory/sql/sp_head::main_mem_root                                              | 3.21 GiB      | 3.62 GiB    | | memory/innodb/hash0hash                                                        | 210.16 MiB    | 323.63 MiB  | | memory/sql/TABLE                                                               | 183.82 MiB    | 190.28 MiB  | | memory/sql/Query_cache                                                         | 128.02 MiB    | 128.02 MiB  | | memory/mysys/KEY_CACHE                                                         | 64.00 MiB     | 64.00 MiB   | | memory/innodb/log0log                                                          | 32.08 MiB     | 32.08 MiB   | | memory/innodb/parallel_doublewrite                                             | 30.27 MiB     | 30.27 MiB   | | memory/performance_schema/table_handles                                        | 27.19 MiB     | 27.19 MiB   | | memory/innodb/mem0mem                                                          | 19.14 MiB     | 20.79 MiB   | | memory/performance_schema/events_statements_history_long                       | 13.66 MiB     | 13.66 MiB   | | memory/performance_schema/events_statements_summary_by_digest.tokens           | 9.77 MiB      | 9.77 MiB    |

另外,如果我们在内存监控表,看见一些比较陌生的event,可以翻阅官方文档或源码,继续进一步解读,例如

memory/innodb/os0event

/** @file include/os0event.h   The interface to the operating system condition variables     Created 2012-09-23 Sunny Bains (split from os0sync.h)   *******************************************************/

memory/innodb/hash0hash

/** @file include/hash0hash.h   The simple hash table utility     Created 5/20/1997 Heikki Tuuri   *******************************************************/

四、总结

总的来说,只要我们的操作系统/数据库有一个相对合理的配置(NUMA、swapiness、jemalloc 、innodb_buffer_pool_size等等),大多数情况是不需要关注内存问题的; 如果非常不幸运地碰到内存占用异常问题,可以通过官方提供的实时监控工具——内存监控表,快速进行定位; 不过需要注意的是,开启内存采集器也会带来一些问题,比如额外的内存占用和性能损耗,一般建议是在系统出现内存问题之后,再重启实例启用,并等待复现。

"有哪些数据库内存知识点"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

内存 大小 监控 分配 情况 缓冲 数据 实例 分配器 系统 采集器 问题 命令 运行 知识 最大 方法 纬度 线程 观察 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 浙江冠钰网络技术有限公司 人事资源有没有共同数据库 天津特种网络技术服务推广 软件开发版权如何约定 话务员招聘软件开发 软件开发公司如何接外包 去互联网还是去银行科技部 软件开发会用到哪些软件 精益创业法管理软件开发项目 深圳世纪速联网络技术 虚拟网络技术操作管理工程师 沁县天气预报软件开发 数据库原理自考知识点 网络安全研究生毕业生工资 网络技术安全A卷 启牛学堂网络安全吗 平安银行网络安全消保主题 数字信息科技互联网之间的关系 熙派互联网科技有限公司 z690支持服务器内存吗 BIM属于软件开发吗 wow 服务器断开 普陀区进口软件开发品牌 移动云倍互联网科技有限公司 网络技术对人才的要求 为什么发邮件对方服务器未响应 数据库技术难学吗 软件开发什么大学 网络安全技术接入交换机部署 计算机软件开发考试时间
0