linux数据库服务器占用内存过高,是怎么回事

linux数据库服务器占用内存过高,是怎么回事,第1张

修改mysql配置文件,优化缓存大小和连接数连接方式,优化sql语句 ,记得mysql好像是有工具可以查看最占用资源的sql语句,找到他,优化他。
安装好mysql后,配制文件应该在/usr/local/mysql/share/mysql目录中,配制文件有几个,有my-hugecnf my-mediumcnf my-largecnf my-smallcnf,不同的流量的网站和不同配制的服务器环境,当然需要有不同的配制文件了。
一般的情况下,my-mediumcnf这个配制文件就能满足我们的大多需要;一般我们会把配置文件拷贝到/etc/mycnf 只需要修改这个配置文件就可以了,使用mysqladmin variables extended-status –u root –p 可以看到目前的参数,有3个配置参数是最重要的,即key_buffer_size,query_cache_size,table_cache。
key_buffer_size只对MyISAM表起作用,
key_buffer_size指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。一般我们设为16M,实际上稍微大一点的站点 这个数字是远远不够的,通过检查状态值Key_read_requests和Key_reads,可以知道key_buffer_size设置是否合理。比例 key_reads / key_read_requests应该尽可能的低,至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE ‘key_read%’获得)。 或者如果你装了phpmyadmin 可以通过服务器运行状态看到,笔者推荐用phpmyadmin管理mysql,以下的状态值都是本人通过phpmyadmin获得的实例分析:
这个服务器已经运行了20天
key_buffer_size – 128M
key_read_requests – 650759289
key_reads - 79112
比例接近1:8000 健康状况非常好

打开SQL Server Profiler
新建跟踪
a点击新建跟踪,并设置好数据库连接
b设置跟踪属性,选择模板“Standard”
c切到“事件选择”进行跟踪设置
1) 只保留如下两个事件选项
2) 点击列筛选
3) 进行详细筛选设置
设置CPU时间作为筛选条件,单位毫秒(用于跟踪耗CPU占用较长的查询,可设置为大于等于20000,按CPU内核数×1000,可以跟踪CPU占用100%大于1秒的查询)
点击运行,跟踪语句,定位CPU占用较多的语句
如下图所示,CPU占用2660146毫秒,CPU为24 核,则至少CPU占用100%耗时2660146/24/1000 = 110秒才可以执行好相应的 *** 作
4
根据语句特征,在你的服务器程序中找到相应的功能,作出修正
41) 分析查询中需要检索数据量较大的部分,作出简单修正(如注销)
42) 更新后重新执行此查询,查看profiler中是否CPU占用消失
43) 如果已消失说明问题定位正确,可以优化查询,若CPU占用任然很多,则回滚修改,继续41 *** 作

这个要看你的SQL语句是怎么写的啦!
索引要建在查询的关键字段上、还有表连接的字段上,如果乱建索引反而会影响系统效率!
IN和NOT IN,EXISTS和NOT EXISTS 这样的SQL语句最好是能不用就不用。很影响效率!
如果非用不可,以下有个结论:
在未对表进行分析前,若两个表数据量差异很大,则外层表是大表时使用IN较快,
外层表是小表时使用EXISTS较快;若两表数据量接近,则使用IN较快;
分析表后无论用IN还是EXISTS都变得更快,由于执行计划一样,所以速度一样;

增加SQL服务器内存,可以减少CPU占用
一般SQL占用CPU,可能的原因:
1、你的网站访问量很大,SQL请求处理量巨大
2、你的SQL数据库很大,或结构很复杂
3、你的程序不在停的循环请求SQL数据库处理。

CPU占用过高诊断思路

mpstat -P ALL 1,查看cpu使用情况,主要消耗在sys即os系统调用上

perf top,cpu主要消耗在_spin_lock

生成perf report查看详细情况

CPU主要消耗在mutex争用上,说明有锁热点。

采用pt-pmp跟踪mysqld执行情况,热点主要集中在mem_heap_alloc和mem_heap_free上。

Pstack提供更详细的API调用栈

Innodb在读取数据记录时的API路径为

row_search_for_mysql --》row_vers_build_for_consistent_read --》mem_heap_create_block_func --》mem_area_alloc --》malloc --》  _L_unlock_10151 --》__lll_unlock_wait_private

row_vers_build_for_consistent_read会陷入一个死循环,跳出条件是该条记录不需要快照读或者已经从undo中找出对应的快照版本,每次循环都会调用mem_heap_alloc/free。

而该表的记录更改很频繁,导致其undo history list比较长,搜索快照版本的代价更大,就会频繁的申请和释放堆内存。

Linux原生的内存库函数为ptmalloc,malloc/free调用过多时很容易产生锁热点。

当多条 SQL 并发执行时,会最终触发os层面的spinlock,导致上述情形。

解决方案

将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。

修改mycnf,添加如下参数并重启

[mysqld_safe]malloc-lib=tcmalloc

上周五早上7点执行的 *** 作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。

以下是修改前后cpu使用率对比

按以下步骤排查问题:
1、代码中是否加锁,某些地方使用了同步方法?锁使用错误导致线程死锁或阻塞;
2、数据层问题,是否使用了框架,比如mybatis,hibernate?,或者使用JDBC直连?
3、有没有使用数据库连接池?如果使用了连接池排查连接池配置是否有问题,最大连接数等,当最大连接数过小时导致大量线程处于等待获取数据库连接状态,或者 *** 作完成后连接没有及时返还给连接池?
4、如果使用的jdbc连接请检查连接使用完后有没有及时释放,如果没有及时释放链接会导致连接越来越多,最后CPU使用率飙高。

1、SQL Server 作为一个数据库服务系统,它的作用就是以尽可能高效、实用的方式管理数据,所以,它占用服务器内存高是很普遍的现象。
2、但是如果在SQL数表设计、存储过程代码编写、临时表的应用中,不注意考虑内存占用与释放,CPU运算,可能会额外的造成不必要的内存占用、CPU占用等。
3、SQL Server在运行过程中,一般会以它认为需要的量去占用内存,对于企业实际运行的SQL Server来说,一般都使用专业级别的服务器,一般都配上几十甚至上百G的内存,不过,即便是这样,内存也不一定够,它基本上会把设定为它可以用的内存给吃干净。因为它的目标就是以最高的效率查找和提供数据。
4、如果它的内存占用你受不了,让你的电脑没法正常运作了,那你可以设定它的最大内存占用,一般去SQL Server管理工具中,找服务器的属性,然后找到相关的参数,作个调整即可。
5、如果你是在你工作或娱乐的电脑上安装了一个SQL Server,用于工作或学习,那么,在不用时,停止SQL Server相关服务,内存即可被基本完全空出(它对CPU的占用也会停止)。(SQL Server 2000及以前版本在托盘中有一个小工具可以控制起动或停止,其后的版本,需要去控制面版中的“服务”中去停相关的应用。)

解决方案

将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。

修改mycnf,添加如下参数并重启

[mysqld_safe]malloc-lib=tcmalloc

上周五早上7点执行的 *** 作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。

以下是修改前后cpu使用率对比


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13317216.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-13
下一篇 2023-07-13

发表评论

登录后才能评论

评论列表(0条)

保存