CentOS 7上MySQL 5.7.18莫名其妙Crash原因分析及解决

一、Centos中查看nginx、apache、php、mysql配置文件路径

1、判断apache
首先执行命令找到httpd路径
ps aux | grep httpd
如httpd路径为 /usr/local/apache/bin/httpd
然后执行以下命令
/usr/local/apache/bin/httpd -V | grep “SERVER_CONFIG_FILE”
即可找到编译时加载的配置文件路径 httpd.conf
-V 参数可以看到编译时配置的参数


2、判断nginx
首先执行命令找到nginx路径
ps aux | grep nginx
如nginx路径为
/usr/local/nginx/sbin/nginx
然后执行以下命令
/usr/local/nginx/sbin/nginx -V
默认放在安装目录下 conf/nginx.conf
3、判断MySQL
首先执行命令找到mysql路径
ps aux | grep mysqld
如mysqld路径为
/usr/bin/mysql
然后执行以下命令
/usr/bin/mysql –verbose –help | grep -A 1 ‘Default options’

/usr/bin/mysql –print-defaults
4、判断PHP加载的配置文件路径
(1)、可通过php函数phpinfo来查看,写个文件,然后用网址访问一下,查找“LoadedConfiguration File”对应的值即为php加载的配置文件
(2)、如果是nginx+php配置,也可以通过查找php执行路径
ps aux | grep php
如,路径为/usr/local/nginx/sbin/php-fpm
然后执行以下命令
/usr/local/nginx/sbin/php-fpm -i | grep “Loaded Configuration File”
即可看到php加载的配置文件
(3)、如果是apache+mod_php配置,也可以在apache配置文件中查看加载的php.ini路径。如 PHPIniDir“/usr/local/apache/conf/php.ini”
当然也有简单的方法,就是通过find来搜索

find / -name nginx.conf
find / -name php.ini
find / -name my.cnf
find / -name httpd.conf

二、查看硬盘和内存

df -h
free -m

三、通过查看MySQL的log确定问题原因

vim /etc/my.cnf

vim /var/log/mysqld.log

2017-06-12T09:07:20.783343Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2017-06-12T09:07:20.786129Z 0 [Note] /usr/sbin/mysqld (mysqld 5.7.18) starting as process 22365 ...
2017-06-12T09:07:20.791952Z 0 [Note] InnoDB: PUNCH HOLE support available
2017-06-12T09:07:20.792024Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2017-06-12T09:07:20.792034Z 0 [Note] InnoDB: Uses event mutexes
2017-06-12T09:07:20.792042Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2017-06-12T09:07:20.792049Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3
2017-06-12T09:07:20.792057Z 0 [Note] InnoDB: Using Linux native AIO
2017-06-12T09:07:20.792523Z 0 [Note] InnoDB: Number of pools: 1
2017-06-12T09:07:20.792716Z 0 [Note] InnoDB: Using CPU crc32 instructions
2017-06-12T09:07:20.795112Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2017-06-12T09:07:20.795195Z 0 [ERROR] InnoDB: mmap(137428992 bytes) failed; errno 12
2017-06-12T09:07:20.795213Z 0 [ERROR] InnoDB: Cannot allocate memory for the buffer pool
2017-06-12T09:07:20.795224Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2017-06-12T09:07:20.795241Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2017-06-12T09:07:20.795248Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2017-06-12T09:07:20.795255Z 0 [ERROR] Failed to initialize plugins.
2017-06-12T09:07:20.795263Z 0 [ERROR] Aborting

2017-06-12T09:07:20.795296Z 0 [Note] Binlog end
2017-06-12T09:07:20.795378Z 0 [Note] Shutting down plugin 'CSV'
2017-06-12T09:07:20.795774Z 0 [Note] /usr/sbin/mysqld: Shutdown complete

四、解决方案
内存不够MySQL分配导致,因此:

(1) 增加物理内存,考虑成本,暂不增加
(2) 分配SWAP空间。方法参考如下:

SWAP是Linux中的虚拟内存,用于扩充物理内存不足而用来存储临时数据存在的。它类似于Windows中的虚拟内存。在Windows中,只可以使用文件来当作虚拟内存。而linux可以文件或者分区来当作虚拟内存。

首先查看当前的内存和swap 空间大小(默认单位为k, -m 单位为M):

free -m

此处可以看到总内存是503M,SWAP不存在。

查看swap信息,包括文件和分区的详细信息

# swapon -s
或者

# cat /proc/swaps
如果都没有,我们就需要手动添加交换分区。注意,OPENVZ架构的VPS是不支持手动添加交换分区的。

添加交换空间有两种选择:添加一个交换分区或添加一个交换文件。推荐你添加一个交换分区;不过,若你没有多少空闲空间可用, 则添加交换文件。

一、增加swap交换文件

1、使用dd命令创建一个swap交换文件

dd if=/dev/zero of=/home/swap bs=1024 count=1024000
这样就建立一个/home/swap的分区文件,大小为1G。

2、制作为swap格式文件:

mkswap /home/swap
3、再用swapon命令把这个文件分区挂载swap分区

/sbin/swapon /home/swap
我们用free -m命令看一下,发现已经有交换分区了。

但是重启系统后,swap分区又变成0了。

4、为防止重启后swap分区变成0,要修改/etc/fstab文件

vi /etc/fstab
在文件末尾(最后一行)加上

/home/swap swap swap default 0 0
这样就算重启系统,swap分区还是有值。

删除swap交换文件

1、先停止swap分区

/sbin/swapoff /home/swap
2、删除swap分区文件

rm -rf /home/swap
3、删除自动挂载配置命令

vi /etc/fstab
这行删除

/home/swap swap swap default 0 0
这样就能把手动增加的交换文件删除了。
注意:
1、增加删除swap的操作只能使用root用户来操作。
2、装系统时分配的swap分区貌似删除不了。
3、swap分区一般为内存的2倍,但最大不超过2G

 

二、使用分区来做SWAP(虚拟内存).
1  使用fdisk来创建交换分区(假设 /dev/sdb2 是创建的交换分区)
2 使用 mkswap 命令来设置交换分区:

# mkswap /dev/sdb2
3 启用交换分区:

# swapon /dev/sdb2
4 写入/etc/fstab,以便在引导时启用:

/dev/sdb2 swap swap defaults 0 0
删除交换分区
步骤如下:
1、先停止swap分区

/sbin/swapoff /dev/sdb2
2、删除自动挂载配置命令

vi /etc/fstab
这行删除

/dev/sdb2 swap swap defaults 0 0
这样就能把手动增加的交换分区删除了。

 

(3) 如果还不行,可以减小MySQL缓存池大小:
## Edit /etc/my.cnf, and add the following line under the [mysqld] heading.
[mysqld]
innodb_buffer_pool_size=64M

(4) 重启mysql服务:service mysqld restart
五、补充阅读

1. Check the permission of mysql data dir using below command
# ls -ld /var/lib/mysql/

2. Check the permission of databases inside mysql data dir using below command
# ls -lh /var/lib/mysql/

3. Check the listening network tcp ports using below command
# netstat -ntlp

4.Check the mysql log files for any error using below command.
# cat /var/log/mysql/mysqld.log

5. Try to start mysql using below command
# mysqld_safe –defaults-file=/etc/my.cf

参考:
http://www.webtrafficexchange.com/solved-mysql-crash-fatal-error-cannot-allocate-memory-buffer-pool
https://stackoverflow.com/questions/34113689/job-for-mysqld-service-failed-centos-7
https://www.huzs.net/?p=1683

 

欢迎关注我的微信公众号:

 

如无特殊说明,文章均为本站原创,转载请注明出处!

《CentOS 7上MySQL 5.7.18莫名其妙Crash原因分析及解决》有一个想法

发表回复

您的电子邮箱地址不会被公开。