MySQL-负载很高排查思路

本文介绍了一套用于诊断MySQL高负载问题的方法,包括使用htop、dstat等工具监控CPU及IO负载,通过tcpdump捕获SQL查询并分析,利用strace检查系统调用异常,以及调整MySQL配置参数。
ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

思路:
1、确定高负载的类型 htop,dstat命令看负载高是CPU还是IO
2、监控具体的sql语句,是insert update 还是 delete导致高负载
3、检查mysql日志
4、检查硬件问题

dstat

可以看到具体是哪个用户哪个进程占用了相关系统资源,当前CPU、内存谁在使用

htop

htop是top的增强版,更直观

tcpdump

抓取mysql包分析,一般抓3306端口的数据

[root@cc ~]# tcpdump -i eth0 -A -s 3000 port 3306 > ~/sql.log

然后使用awk,sort,wc 等命令进行分析

或者

[root@cc ~]# tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
    if (defined $q) { print "$qn"; }
    $q=$_;
    } else {
    $_ =~ s/^[ t]+//; $q.=" $_";
    }
}'

就可以看出最繁忙的sql语句了

strace

查看系统调用是否有问题,进程是否堵塞,是否有Broken pipe

[root@cc ~]# strace -p 26578

pt-query-digest

分析mysql慢日志,查看哪些sql语句最耗时

[root@cc ~]#  pt-query-digest slow.logs

# 390ms USER TIME, 10ms system TIME, 15.67M rss, 105.84M vsz  
# CURRENT DATE: Thu DEC 29 13:22:42 2014  
# Hostname: test   
# Files: slow.log  
# Overall: 776 total, 11 UNIQUE, 0.00 QPS, 0.00x concurrency _____________  
# TIME range: 2011-09-10 04:03:19 TO 2011-12-29 05:02:51  
# Attribute          total     MIN     MAX     avg     95%  stddev  median  
# ============     ======= ======= ======= ======= ======= ======= =======  
# EXEC TIME          5657s      2s     33s      7s     23s      6s      5s  
# LOCK TIME            33s       0     19s    43ms    98us   715ms    38us  
# ROWS sent        323.38k       0 107.36k  426.73    0.99   6.35k       0  
# ROWS examine     323.39k       0 107.36k  426.74       0   6.35k       0  
# Query SIZE       217.95k      38     562  287.61  420.77   81.78  284.79  

show processlist

查看系统到底在干什么


mysql> show full processlist;
+-----------+---------------+---------------------+---------------------+---------+------+---------------+---------------------------+
| Id        | User          | Host                | db                  | Command | Time | State         | Info                      |
+-----------+---------------+---------------------+---------------------+---------+------+---------------+---------------------------+
| 184498848 | testdb_rr1356 | 10.11.211.120:61343 | testdb_rr1356_db121 | Sleep   | 1384 |               | NULL                      |
| 184508740 | testdb_rr1356 | 10.11.211.120:11809 | testdb_rr1356_db121 | Sleep   |   87 |               | NULL                      |
| 184509415 | testdb_rr1356 | 10.11.211.120:12760 | testdb_rr1356_db121 | Query   |    0 | NULL          | show full processlist     |
| 184509451 | testdb_rr1356 | 10.11.211.120:12804 | testdb_rr1356_db121 | Sleep   |   10 |               | NULL                      |
| 184509528 | testdb_rr1356 | 10.11.211.120:12919 | testdb_rr1356_db121 | Query   |    0 | freeing items | DESCRIBE test_channel     |

检查mysql配置参数是否有问题,引起大量的IO或者高CPU操作

innodb_flush_log_at_trx_commit 、innodb_buffer_pool_size 、key_buffer_size 等重要参数

mysql> show variables like '%innodb%';
+---------------------------------+----------------------------+
| Variable_name                   | Value                      |
+---------------------------------+----------------------------+
| have_innodb                     | YES                        |
| ignore_builtin_innodb           | ON                         |
| innodb_adaptive_flushing        | ON                         |
| innodb_adaptive_hash_index      | ON                         |
| innodb_additional_mem_pool_size | 2097152                    |
| innodb_autoextend_increment     | 8                          |
| innodb_autoinc_lock_mode        | 1                          |
| innodb_buffer_pool_size         | 2013265920                 |
| innodb_change_buffering         | inserts                    |
| innodb_checksums                | ON                         |

通过show engine innodb status查看当前事务,内存使用

mysql> show engine innodb status  \G

LATEST DETECTED DEADLOCK
------------------------
150731 10:36:50
*** (1) TRANSACTION:
TRANSACTION EBFBBEC, ACTIVE 0 sec, process no 20691, OS thread id 47345217033984 inserting
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1248, 4 row lock(s), undo log entries 2
MySQL thread id 143249904, query id 1286731854 10.135.21.120 tybuser2014 update

#此处具体sql省略

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 2058485760; in additional pool allocated 0
Dictionary memory allocated 819282
Buffer pool size   122879
Free buffers       97599
Database pages     24313
Old database pages 8954
Modified db pages  7
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 6, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 1049, created 41853, written 30401604
0.00 reads/s, 0.00 creates/s, 1.75 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 24313, unzip_LRU len: 0
I/O sum[45]:cur[0], unzip sum[0]:cur[0]

最后通过zabbix或者cacti等监控来查看IO、CPU、MEMORY、磁盘等是否有异常

这样基本上就可以把问题找出来了

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>好的,我现在需要帮助用户解决MySQL的Swap使用率过的问题。首先,我得回忆一下Swap相关的知识。Swap是当物理内存不足时,系统将部分内存数据转移到磁盘上的空间,这会导致性能下降,尤其是对于数据库如MySQL来说,频繁的Swap交换会严重影响性能。 用户的问题是如何排查这个问题,所以我要分步骤来思考。首先,可能需要确认Swap使用率确实很高。这可以通过哪些命令呢?比如free -h或者top,还有swapon -s来查看Swap分区情况。 接下来,需要找出哪个进程占用了大量内存,导致系统开始使用Swap。这时候常用的命令是top或htop,按内存排序,看看MySQL是否是内存消耗最大的进程。如果是,那可能MySQL本身配置有问题,或者查询效率低下导致内存不足。 然后,检查MySQL的内存使用情况。MySQL有几个重要的内存参数,比如innodb_buffer_pool_size、key_buffer_size、query_cache_size等。如果这些配置不合理,可能导致物理内存不足,进而触发Swap。这时候需要查看MySQL的配置文件,通常是my.cnf或my.ini,确认这些参数的设置是否合适。 另外,系统级别的内存使用情况也需要检查。使用free -m查看总内存和Swap使用情况,或者vmstat 1来看实时内存、Swap的in/out情况。如果系统的空闲内存很少,即使MySQL配置正确,也可能因为其他进程占用内存而引发Swap。 还有一个方面是查看是否有内存泄漏或者某个查询消耗了大量内存。可以通过MySQL的慢查询日志来识别效率低下的查询,或者使用SHOW PROCESSLIST来查看当前执行的查询,看是否有长时间运行或消耗资源的操作。 此外,操作系统的swappiness参数也可能影响Swap的使用。swappiness值越,系统越倾向于使用Swap。可以通过cat /proc/sys/vm/swappiness查看,默认值通常是60。对于数据库服务器,建议将这个值调低,比如10或更低,以减少Swap倾向。 还有可能需要检查磁盘I/O情况,因为Swap使用过多会导致磁盘I/O增加,进一步降低性能。可以用iostat或iotop来查看磁盘的IO负载。 总结下来,排查步骤大致如下: 1. 确认Swap使用情况。 2. 确定占用内存的进程。 3. 检查MySQL内存配置。 4. 分析系统内存和swappiness设置。 5. 检查查询优化和慢查询。 6. 调整系统参数和MySQL配置。 7. 监控和测试调整后的效果。 需要注意的是,调整配置后可能需要重启MySQL或系统才能生效。同时,监控工具如Prometheus、Grafana或者MySQL自带的监控工具可以帮助长期观察内存和Swap的使用趋势,预防问题再次发生。 可能遇到的误区是,只调整swappiness而忽视MySQL自身的内存配置,或者没有正确评估系统总内存是否足够。因此,综合考虑系统整体内存使用和MySQL的配置是关键。</think>### MySQL Swap使用率排查步骤 --- #### 一、确认Swap使用情况 1. **查看Swap占用** 执行命令确认系统Swap使用率: ```bash free -h # 查看内存和Swap总量及使用率 top # 按`Shift+W`保存配置,按`E`切换内存单位 swapon -s # 查看Swap分区信息 ``` 2. **定位进程内存占用** 找到占用物理内存最多的进程: ```bash top -o %MEM # 按内存占用排序 或 htop # 交互式工具(需安装) ``` --- #### 二、检查MySQL内存配置 1. **关键参数核对** MySQL配置文件(`my.cnf`或`my.ini`)中以下参数需合理分配: ```ini innodb_buffer_pool_size = 物理内存的50%~70% key_buffer_size = 非InnoDB表专用(通常<512M) query_cache_size = 建议关闭(设置为0) tmp_table_size = 避免过大(默认16M~64M) max_connections = 避免过(根据实际调整) ``` > **公式参考**: > $$总内存 \geq innodb\_buffer\_pool\_size + key\_buffer\_size + (max\_connections \times per\_thread\_memory)$$ 2. **查看当前内存分配** 登录MySQL执行: ```sql SHOW VARIABLES LIKE '%buffer%'; SHOW VARIABLES LIKE '%cache%'; SHOW VARIABLES LIKE 'max_connections'; ``` --- #### 三、分析系统内存压力 1. **检查系统内存余量** ```bash vmstat 1 # 查看si(Swap In)、so(Swap Out)是否频繁 sar -r 1 # 监控内存和Swap变化 ``` 2. **调整Swappiness参数** ```bash cat /proc/sys/vm/swappiness # 默认值60(范围0-100) sysctl vm.swappiness=10 # 临时生效 echo "vm.swappiness=10" >> /etc/sysctl.conf # 永久生效 ``` --- #### 四、优化MySQL行为 1. **排查慢查询与临时表** - 开启慢查询日志: ```ini slow_query_log = ON long_query_time = 2 ``` - 检查执行计划: ```sql EXPLAIN [你的慢SQL]; ``` - 监控临时表: ```sql SHOW STATUS LIKE 'Created_tmp%'; ``` 2. **控制连接数与线程缓存** - 限制空闲连接: ```sql SET GLOBAL wait_timeout = 600; # 默认28800秒(8小时) ``` - 查看线程内存: ```sql SHOW VARIABLES LIKE 'thread_stack'; # 默认256KB~1MB ``` --- #### 五、级诊断工具 1. **内存泄漏检测** 使用`valgrind`或`jemalloc`工具监控MySQL内存分配。 2. **PMO(Page Management Overhead)** ```bash mysqladmin ext -i1 | grep "Innodb_buffer_pool_pages" # 关注`Innodb_buffer_pool_pages_free`是否接近0 ``` --- #### 六、应急措施 1. **临时释放Swap** ```bash swapoff -a && swapon -a # 清空Swap(需确保物理内存足够) ``` 2. **重启MySQL** ```bash systemctl restart mysql # 强制释放内存(谨慎操作) ``` --- #### 附:常见配置错误示例 ```ini # 错误:innodb_buffer_pool_size超过物理内存80% innodb_buffer_pool_size = 16G # 服务器总内存仅20G # 错误:max_connections过(默认151) max_connections = 1000 # 导致per-thread内存爆炸 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值