新公司的系统一直很不稳定,店面销售人员经常报登不上系统或速度奇慢的情况,怀疑可能是代码存在数据库连接泄露及内存泄露现象,离春节只有几天时间,也来不急进行代码调优,只有从配置层面看有那些手段来采用,以便暂且缓解一下服务器压力,降低系统的故障率。为了第一时间能够知道服务器故障,基于nagios搭建了服务器监控程序,这样系统有故障时候,能够用短信方式通知系统故障,及时解决。
1、系统情况:
操作系统:Redhat AS4
数据库:mysql 4.1.18
应用服务器:JBoss 3.2.7
服务器: 4 x3.00GHz的Intel Xeon CPU
数据库和应用服务器都部署在同一台服务器上。
简单跟踪了一下,发现平常内存、io负载都不大,数据库连接数也不多。只是很奇怪的是mysql的cpu负载始终是99.9%,但整个系统的速度还行,开始怀疑是JVM、数据库参数、索引没有优化导致的,因此先着手对java虚拟机参数及数据库参数进行了调整。
2、java虚拟机调优
- 调整虚拟机的参数
JAVA_OPTS=”$JAVA_OPTS -Xms512m -Xmx1024m -server -XX:MaxPermSize=300m -XX:MaxNewSize=300m”
- 调整jboss的数据库连接池,修改最大连接数及连接回收时间
<min-pool-size>20</min-pool-size>
<max-pool-size>300</max-pool-size>
<idle-timeout-minutes>1</idle-timeout-minutes>
<min-pool-size>20</min-pool-size>
3、数据库调优
- 对所有的表,优化及增加索引。
发现一个好用的mysql工具navicat,感觉比ems 好用,用这东西增加索引方便多了。
- 调整mysql参数
原来是基于my-medium.cnf 修改的参数,由于担心是大数据量查询sort区等不够及程序存在内存泄露问题,因此基于my-huge.cnf进行调整。
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-locking
key_buffer = 256M
max_allowed_packet = 1M
table_cache = 256
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 2M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 32M
thread_concurrency = 8
max_connections=300
#skip-networking
#log-bin
server-id = 1
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
#safe-updates
[isamchk]
key_buffer = 128M
sort_buffer_size = 128M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 128M
sort_buffer_size = 128M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
调整后,支撑了3天左右,除了mysql的cpu占用始终是99%外,系统整体运行基本正常,忙于其他事情,没有继续跟踪。没想到大年初一接了一堆报警短信,执行查看了系统参数,发现系统竟然没有swap区,欣喜一阵,可能是这原因吧,于是临时建立swap区。
4、增加swap区
-
在/swap下生成1G的文件
# mkdir /swap
# dd if=/dev/zero of=/swap/swapfile bs=500M count=2
- 创建为swap文件
#mkswap /swap
-
让swap生效
#swapon /swap
- 查看一下swap
#swapon -s
- 把新增的swap文件加到fstab文件中让系统引导时自动启动
#vi /etc/fstab
/swap/swapfile swap swap defaults 0 0
增加后,重启应用及服务,mysql的cpu占用还是持续性为99.9%,而且运行上一段时间还是出现无法登录的情况。远程登录到系统,发现内存、io、swap区占用都很正常,数据库连接数也很正常,而且在停止mysql和jboss后,直接重启jboss,不能正常启动成功,需要等上一会儿,怀疑是文件句柄及tcp连接尚未正常释放。联系以前遇到的情况,怀疑与操作系统允许的最大句柄数有关。
用ulimit -a|grep open 命令查看了结果为:
open files (-n) 1024
用cat /proc/sys/fs/file-max查看结果为:
379816
由于数据库和jboss同时部署在同一台服务器上,在负荷较小的情况下用lsof -u root |wc -l查看root用户的句柄数仍然为700多,因此在负荷较高的情况下,用户的最大句柄数1024是有点小。
5、修改操作系统句柄数
5.1、修改操作系统的最大限制数
- 修改 /etc/sysctl.conf
增加fs.file-max = 8061540
- 在/etc/pam.d/login 中添加
session required /lib/security/pam_limits.so
- 在/etc/security/limits.conf 中添加
root – nofile 1006154
修改root用户的句柄数(包括hard和soft)限制为1006154
- 修改 /etc/rc.local 添加
echo 8061540 > /proc/sys/fs/file-max
5.2、修改用户最大限制数
考虑到重启服务器的风险,先暂时修改一下启动jboss的root用户的/root/.bash_profile,增加如下内容:
ulimit -n 65535
重启jboss和mysql。
连续观察了几天,发现cpu始终占用99.9%的情况解决掉了,继续观察中。
6、参考文档
http://www.bea.com.cn/support_pattern/Too_Many_Open_Files_Pattern.html
http://kbase.redhat.com/faq/FAQ_80_1540.shtm
转载请注明:出家如初,成佛有余 » mysql 数据库cpu 占用99.9%问题调优札记