MySQL的Sleep进程占用大量连接解决方法

本文详细解析了MySQL中出现大量Sleep进程的原因及解决方法,包括采用短链接、优化网页脚本、适当调整参数等策略,以及通过设置wait_timeout有效减少睡眠进程。文章还提供了设置wait_timeout的方法,包括修改配置文件和在MySQL命令行中设置,并解释了如何区分会话变量和全局变量。

MySQL的Sleep进程占用大量连接解决方法

链接:http://hi.baidu.com/ratmin/item/eaab88ca9addd425a1b50a74

==========================================

第一部分为产生大量sleep进程的原理及对应解决方法
第二部分为设置wait_timeout值,有效减少sleep进程

==========================================
第一部分开始

1、通常来说,MySQL出现大量Sleep进程是因为采用的PHP的MySQL长链接数据库方式,即使用了mysql_pconnect来打开链接数据库,解决办法就是使用“短”链接,即mysql_connect函数。

2、在使用mysql_connect短链接方式打开数据库,每个页面在打开数据库后,执行SQL完成,当页面脚本结束的时候,这个MySQL连接会自动关闭并且释放内存。但仍然出现大量Sleep进程,可以看看网站是否存在以下几个方面的问题。

A,硬盘上存在大量的静态文件,或者WEB服务器负荷太重,在处理HTTP请求响应变得太慢,这样也有可能导致出现大量Sleep进程,解决方法适当调整WEB服务参数和文件,一味的静态或者缓存化网页内容并不是灵丹妙药。

B,在网页脚本中,有些计算和应用可能非常耗时,比如在0秒的时候打开数据库执行完一段SQL代码后,网页脚本随即花了20秒钟进行一段复杂的运算,或者是require了一个庞大的PHP文件(比如含有几千个违规关键字的过滤函数),哪么这个时候在MySQL后台看到的进程中,这个20秒的过程MySQL并没有做任何事情了,一直处于Sleep状态,直到这个页面执行完毕或者达到wait_timeout值(被强行关闭),优化网页脚本,尽量让程序快速运行,或者在执行这段耗时的运行过程中,执行mysql_close把当前MySQL链接强行关闭。

C,在采集站中,MySQL中大量的Sleep进程这类现象尤其明显(比如很多网友问道DeDeCMS的MySQL中出现大量Sleep),因为大部的采集器页面在运行过程中,事先打开了一个MySQL链接(可能是为了验证用户权限等),然后开始使用file_get_contents之类的操作去获取一个远程的网页内容,如果这个远程的站点访问速度太慢,比如花了10秒时间才把网页取回,哪么当前采集脚本程序就一直阻塞在这里,并且MySQL啥事也没干,一直处于Sleep状态。解决方法同上,在发出file_get_contents采集远程网页的时候,使用mysql_close强行关闭MySQL的连接,等采集完成在适当需要的时候再重新mysql_connect即可。

==========================================

第二部分开始

设置wait_timeout的值,有效减少sleep进程

如果你没有修改过MySQL的配置,缺省情况下,wait_timeout的初始值是28800。

wait_timeout过大有弊端,其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统性能,不过也不能把这个值设置的过小,否则可能会遭遇到“MySQL has gone away”之类的问题(你可以在程序里时不时mysql_ping一下,以便服务器知道你还活着,重新计算wait_timeout时间),使用

mysql>show processlist; 用这个命令来查看当前mysql的进程情况,可以看出大量的sleep进程的时间是多少,大部分的都是10左右的,这时wait_timeout值就可以设置成8-10;

设置wait_timeout的方法有2个:

# vi /etc/my.cnf (在windows下是my.ini)

[mysqld]
wait_timeout=10

# /etc/init.d/mysql restart

这个方法设置后即使服务器以后重启,设置照样生效,不过这个方法会造成mysql服务重启,无论如何都应该尽可能避免;

下面看看在MySQL命令行里通过SET来设置:

mysql> set global wait_timeout=10;

mysql> show global variables like 'wait_timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| wait_timeout               | 10    |
+----------------------------+-------+

这里一个容易把人搞蒙的地方是如果查询时使用的是show variables的话,会发现设置好像并没有生效,这是因为单纯使用show variables的话就等同于使用的是show session variables,查询的是会话变量,只有使用show global variables,查询的才是全局变量。

网络上很多人都抱怨说他们set global之后使用show variables查询没有发现改变,原因就在于混淆了会话变量和全局变量,如果仅仅想修改会话变量的话,可以使用类似set wait_timeout=10;或者set session wait_timeout=10;这样的语法。

这个方法只是临时性的,如果服务器重启后,wait_timeout的值又会变成28800。


<think> 我们面对的问题是MySQL占用CPU高如何解决。需要提供详细的排查步骤和解决方法,并在最后提出相关问题。 思路: 1. 分析可能的原因:查询效率低、锁争用、配置不当、硬件瓶颈、大量连接等。 2. 提供排查工具和步骤:如使用top、SHOW PROCESSLIST、慢查询日志、EXPLAIN等。 3. 给出优化建议:索引优化、查询优化、配置调整、读写分离等。 4. 最后按照要求提出3-5个相关问题。 注意:回答必须用中文,最后必须有“§§相关问题§§”且问题数量在3-5个。 </think> ### MySQL CPU 占用高问题排查与优化指南 #### 一、快速定位问题源 **1. 实时监控工具** ```bash # 查看当前高负载SQL线程 SHOW FULL PROCESSLIST; # 持续监控资源占用(每秒刷新) mysqladmin -u root -p -i 1 processlist ``` **2. 性能诊断工具** ```sql -- 开启性能监控 SET GLOBAL performance_schema=ON; -- 查看CPU消耗TOP5查询 SELECT * FROM sys.statement_analysis ORDER BY avg_cpu_time DESC LIMIT 5; ``` **3. 系统级排查** ```bash # 查看MySQL进程资源占用 top -p $(pgrep mysqld) # 检查IO等待(高IO常伴随高CPU) iostat -xm 2 ``` #### 二、常见原因及解决方案 **1. 低效SQL查询** ```sql -- 1.1 定位慢查询 SHOW VARIABLES LIKE 'slow_query_log'; SET GLOBAL slow_query_log = 'ON'; -- 1.2 分析执行计划 EXPLAIN SELECT * FROM orders WHERE status='PENDING'; -- 1.3 优化案例:添加组合索引 ALTER TABLE orders ADD INDEX idx_status_created(status, created_at); ``` **2. 锁竞争问题** ```sql -- 2.1 查看当前锁状态 SELECT * FROM information_schema.INNODB_LOCKS; -- 2.2 降低隔离级别(RR→RC) SET GLOBAL transaction_isolation='READ-COMMITTED'; -- 2.3 优化事务逻辑 START TRANSACTION; -- 业务操作... COMMIT; -- 缩短事务持有时间 ``` **3. 配置参数不当** ```ini # my.cnf 优化示例 [mysqld] innodb_buffer_pool_size = 物理内存的70% # 减少磁盘IO max_connections = 500 # 避免连接风暴 thread_cache_size = 32 # 减少线程创建开销 query_cache_type = 0 # 禁用易失效的查询缓存 ``` **4. 资源争用场景** ```mermaid graph TD A[CPU高] --> B{检查方向} B --> C[SQL效率] B --> D[锁阻塞] B --> E[连接风暴] B --> F[硬件瓶颈] F --> G[内存不足→SWAP] F --> H[磁盘IOPS超限] ``` #### 三、深度优化方案 **1. 架构层优化** - 读写分离:部署MySQL从库处理查询 - 分库分表:使用sharding-sphere拆分大表 - 热点数据缓存:Redis缓存高频查询结果 **2. InnoDB引擎调优** ```sql -- 减少刷新频次 SET GLOBAL innodb_flush_log_at_trx_commit = 2; SET GLOBAL innodb_io_capacity = 2000; -- 监控Buffer Pool命中率 SHOW STATUS LIKE 'innodb_buffer_pool%'; -- 目标:命中率 > 99% ``` **3. 紧急处理流程** ```bash # 1. 终止问题会话 SELECT CONCAT('KILL ', id, ';') FROM information_schema.processlist WHERE TIME > 300 OR COMMAND='Sleep' INTO OUTFILE '/tmp/kill.sql'; SOURCE /tmp/kill.sql; # 2. 限流保护 # 使用ProxySQL或MySQL企业版线程池 ``` #### 四、监控预警体系 ```yaml # Prometheus监控配置示例 - name: mysql_exporter static_configs: - targets: ['db01:9104'] metrics_path: /metrics params: collect[]: - global_status - innodb_metrics - perf_schema.eventsstatements ``` **关键指标阈值:** | 指标名称 | 警戒值 | 危险值 | |---------------------------|--------|--------| | CPU使用率 | 70% | 90% | | 活跃线程数 | 100 | 200 | | Innodb_row_lock_waits | 5/s | 20/s | | Slow_queries | 10/min | 50/min |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值