WordPress MySQL: Error establishing a database connection
最近几天服务器经常挂掉,在后台提交了工单查询问题的根源,原来是服务器MySQL进程OOM导致被强杀。下面把CentOS服务器MySQL异常的分析过程和内存优化的配置记录如下。
一、MySQL OOM异常分析
1、在异常发生的时候访问网站,加载出来的页面显示的内容只有一行错误文本提示。
Error establishing a database connection
2、打开阿里云轻量应用服务后台,查看网络、CPU和内存的占用,可以看到内存占用异常偏高。
3、既然是数据库连接异常,直接进入到应用详情,远程连接MySQL,这边MySQL的版本是5.7。
4、在连接终端输入命令查看MySQL进程挂掉的原因:
sudo cat /var/log/messages | grep kill
也可以用memory来过滤Log信息:
cat /var/log/messages | grep memory
从上面可以很明确的看到MySQL进程因为内存溢出(OOM)原因被强杀了。
5、接着用如下命令查看内存分配信息
free -m
在控制台可以看到:
total used free shared buff/cache available Mem: 992 368 121 39 502 419 Swap: 0 0 0
总内存992MB,剩余内存free只剩121MB,内存明显不足。
6、接着再用top命令查看一个周期内各个进程CPU和内存的占用率。
top
使用Ctrl+C终止监控,可以看到一个监控周期内,mysqld进程内存占用最高,下面截图是优化配置后mysqld内存占用平均在20.6%,优化配置前mysqld内存占用平均在27%。
二、MySQL内存优化配置-5.7版本
从上面的异常分析可以明确就是内存不足导致的问题,接着着手对MySQL的内存配置进行优化。
1、my.cnf内存配置优化
1)MySQL的内存配置文件在“/etc/my.cnf”路径下,初始这个文件只有可读权限,所以需要先赋予下权限再进行编辑。
sudo chmod 777 /etc/my.cnf
2)接着用以下命令查看文件的读写权限是否修改生效:
ls -l /etc/my.cnf
输出结果显示是“-rwxrwxrwx”就没问题。
-rwxrwxrwx 1 root root 1603 Jul 19 19:28 /etc/my.cnf
3)接着用vim命令打开文件修改配置参数。
vim /etc/my.cnf
初始“my.cnf”文件的配置参数如下:
# For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html # *** DO NOT EDIT THIS FILE. It's a template which will be copied to the # *** default location during install, and will be replaced if you # *** upgrade to a newer version of MySQL. [mysqld] sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES # 一般配置选项 basedir = /usr/local/mysql datadir = /usr/local/mysql/data port = 3306 socket = /tmp/mysql.sock character-set-server=utf8 back_log = 300 max_connections = 1000 max_connect_errors = 50 table_open_cache = 4096 max_allowed_packet = 32M #binlog_cache_size = 4M max_heap_table_size = 128M read_rnd_buffer_size = 16M sort_buffer_size = 16M join_buffer_size = 16M thread_cache_size = 16 query_cache_size = 128M query_cache_limit = 4M ft_min_word_len = 8 thread_stack = 512K transaction_isolation = REPEATABLE-READ tmp_table_size = 128M #log-bin=mysql-bin long_query_time = 6 server_id=1 innodb_buffer_pool_size = 512M innodb_thread_concurrency = 16 innodb_log_buffer_size = 16M innodb_log_file_size = 128M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 90 innodb_lock_wait_timeout = 120 innodb_file_per_table = on [mysqldump] quick max_allowed_packet = 32M [mysql] no-auto-rehash default-character-set=utf8 safe-updates [myisamchk] key_buffer = 16M sort_buffer_size = 16M read_buffer = 8M write_buffer = 8M [mysqlhotcopy] interactive-timeout [mysqld_safe] open-files-limit = 8192 [client]
我所购买的轻量应用服务器套餐内存配置只有1GB,明显上面的配置参数都偏大了,优化之后的配置如下,大部分配置的参数值直接减少到原有的四分一,主要削减innodb_buffer_pool_size,这个占大头:
# For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html # *** DO NOT EDIT THIS FILE. It's a template which will be copied to the # *** default location during install, and will be replaced if you # *** upgrade to a newer version of MySQL. [mysqld] performance_schema=OFF sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES # 一般配置选项 basedir = /usr/local/mysql datadir = /usr/local/mysql/data port = 3306 socket = /tmp/mysql.sock character-set-server=utf8 back_log = 256 max_connections = 256 max_connect_errors = 20 table_open_cache = 256 max_allowed_packet = 8M #binlog_cache_size = 4M max_heap_table_size = 32M read_rnd_buffer_size = 4M sort_buffer_size = 4M join_buffer_size = 4M thread_cache_size = 4 query_cache_size = 32M query_cache_limit = 1M ft_min_word_len = 8 thread_stack = 512K transaction_isolation = REPEATABLE-READ tmp_table_size = 32M #log-bin=mysql-bin long_query_time = 6 server_id=1 innodb_buffer_pool_size = 64M innodb_thread_concurrency = 8 innodb_log_buffer_size = 1M innodb_log_file_size = 8M innodb_log_files_in_group = 3 innodb_max_dirty_pages_pct = 90 innodb_lock_wait_timeout = 120 innodb_file_per_table = on [mysqldump] quick max_allowed_packet = 8M [mysql] no-auto-rehash default-character-set=utf8 safe-updates [myisamchk] key_buffer = 4M sort_buffer_size = 4M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout [mysqld_safe] open-files-limit = 1024 [client]
在控制台打开文件之后,使用按键i进入编辑模式。在参数修改完毕之后,按ESC键退出编辑,接着输入以下命令保存修改并退出。
:wq
上面的命令是基础常用的VIM命令,更多命令资料可参考:
这边就不对上面的配置参数字段作一一说明,更多资料可以参考:
TIPS:
这边特别说下“performance_schema=OFF”参数的配置,MySQL的performance schema用于监控MySQL server在一个较低级别的运行过程中的资源消耗、资源等待等情况,MySQL 5.7之前的版本默认关闭。对于WordPress服务器来说,特别是内存配置较低的服务器,重点还是保证网站访问没问题,监控与否并不重要,可以关闭这个配置。
2、sysctl.conf文件参数配置
如果在分析的时候,查看是Swap中的内存异常导致的OOM,可以到“/etc/sysctl.conf”文件下增加如下配置:
vm.swappiness = 0
我这边查看是默认配置了0,这边也给下阿里云WordPress服务器sysctl.conf里面的默认配置参数:
# sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 vm.swappiness = 0 net.ipv4.neigh.default.gc_stale_time=120 # see details in https://help.aliyun.com/knowledge_detail/39428.html net.ipv4.conf.all.rp_filter=0 net.ipv4.conf.default.rp_filter=0 net.ipv4.conf.default.arp_announce = 2 net.ipv4.conf.lo.arp_announce=2 net.ipv4.conf.all.arp_announce=2 # see details in https://help.aliyun.com/knowledge_detail/41334.html net.ipv4.tcp_max_tw_buckets = 5000 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 1024 net.ipv4.tcp_synack_retries = 2
在做以上优化配置之后,mysqld内存稳定在20%左右,本以为做了优化之后问题不大了,但服务器跑了两天之后,网站又出现无法访问的异常,这下报的是php-fpm oom-killer问题,继续看下一篇:阿里云WordPress Apache服务器内存优化配置
三、参考资料
配置详解 | performance_schema全方位介绍
云服务器 ECS Linux 系统 WordPress 网站访问报错:建立数据库连接时出错
mysql 5.6启动占用物理内存和虚拟内存过高问题处理办法
相关阅读:
转载请注明出处:陈文管的博客 – 阿里云WordPress服务器MySQL内存优化配置
扫码或搜索:文呓
微信公众号 扫一扫关注