Top 命令的输出信息主要分为两部分,上半部分显示 CPU 和内存资源的总体使用情况:
jmap [options] pid
jmap -histo pid | head -20
jps [options] [hostid]
option参数:
参数 | 说明 |
-l | 输出主类全名或jar路径 |
-q | 只输出LVMID |
-m | 输出JVM启动时传递给main()的参数 |
-v | 输出JVM启动时显示指定的JVM参数 |
其中 [option]、[hostid] 参数也可以不写。
进到linux容器中执行 top命令,结果发现高cpu占用,其中pid 为1的正是我们的java程序。
执行命令找出占用CPU最高的线程 top -Hp pid 显示的新pid都是线程,找到占用cpu最高的线程号。
把线程号转换为16进制,便于在jstack中查询 printf "%x " tid 变为16进制。
jstack命令查看相应线程的堆栈 jstack pid | grep 0x十六进制结果 -A30
命令查看进程的堆情况
S0:年轻代中第一个 survivor(幸存区)已使用的占当前容量百分比
S1:年轻代中第二个 survivor(幸存区)已使用的占当前容量百分比
E:年轻代中 Eden 区已使用的占当前容量百分比
O:老年代已使用的占当前容量百分比
M:元数据区使用比例
CCS:压缩使用比例
YGC:从应用程序启动到采样时年轻代中 gc 次数
YGCT:从应用程序启动到采样时年轻代中 gc 所用时间(单位秒)
FGC:从应用程序启动到采样时老年代 full gc 次数
FGCT:从应用程序启动到采样时老年代 full gc 所用时间(单位秒)
GCT:从应用程序启动到采样时 gc 用的总时间(单位秒)
命令导出堆文件,只导出 live 存活的对象。文件后缀名可以是任意的,因为它也是二进制的,不过通常以 hprof 结尾。
操作路径:文件 -> 装入 -> 文件类型选择堆,选中刚才导出的堆文件。
选择类列表,按照大小排序,找出占用内存最大的类别
发现此案例中完全不存在慢sql。因此责任可100%归为qps过高。
从上图我们可看出,cpu和qps的整体的整体走势是基本一致的,但是上图中相对qps曲线,cpu有好几次的抖动,甚至峰值达到80%,我们需要排查出这些峰刺点。
由于此时的cpu抖动和qps曲线不一致,可推测是慢sql引起的,观察下图抖动时间段内的慢sql,确定是否有慢sql,以及慢sql的具体信息。
观察上图发现该时间段内一些慢sql在库上使得cpu曲线发生了抖动,此时可采取kill+id的方法定制该sql的执行。
考虑表是否设置了合理的索引,表字段是否设置了合理的数据类型,sql是否有效的利用了索引等。
考虑将sql简化,把逻辑操作上浮到业务中去做。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16965 mysql 20 0 32.0g 2.8g 16592 S 1566 8.8 49:40.99 mysqld
top -Hp 16965
top -p 16965 -H
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17053 mysql 20 0 32.0g 2.8g 16668 R 62.7 9.0 4:47.45 mysqld
17032 mysql 20 0 32.0g 2.8g 16668 R 61.7 9.0 5:03.16 mysqld
17028 mysql 20 0 32.0g 2.8g 16668 R 61.3 9.0 4:38.47 mysqld
17033 mysql 20 0 32.0g 2.8g 16668 R 61.0 9.0 4:56.53 mysqld
17054 mysql 20 0 32.0g 2.8g 16668 R 59.0 9.0 5:17.14 mysqld
17064 mysql 20 0 32.0g 2.8g 16668 R 59.0 9.0 4:57.18 mysqld
17057 mysql 20 0 32.0g 2.8g 16668 R 57.0 9.0 4:47.68 mysqld
17065 mysql 20 0 32.0g 2.8g 16668 R 56.7 9.0 5:00.24 mysqld
可以看到占用最高的是PID=17053
mysql> select thread_id,name ,PROCESSLIST_ID,THREAD_OS_ID from performance_schema.threads where thread_os_id = 17053;
+-----------+---------------------------+----------------+--------------+
| thread_id | name | PROCESSLIST_ID | THREAD_OS_ID |
+-----------+---------------------------+----------------+--------------+
| 143 | thread/sql/one_connection | 97 | 17053 |
+-----------+---------------------------+----------------+--------------+
1 row in set (0.00 sec)
select DIGEST_TEXT from performance_schema.events_statements_current where thread_id = 143 ;
+---------------------------------------------------------------------+
| DIGEST_TEXT
SELECT * FROM t xxx ……
Mysql 查询是否存在锁表有多种方式,这里只介绍一种最常用的
1、查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX
2、查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
3、查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
4、查询是否锁表
SHOW OPEN TABLES where In_use > 0;
5、查看最近死锁的日志
show engine innodb status
如果需要解除死锁,有一种最简单粗暴的方式,那就是找到进程id之后,直接干掉。
show processlist
SELECT * FROM information_schema.INNODB_TRX;
kill id
SHOW OPEN TABLES where In_use > 0;
页面更新:2024-04-24
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号