记录一次MySQL启动失败,定位问题以及解决问题的过程。
环境
OS:CentOS 7
Memory:512M
SSD:20G
MySQL version:mysql Ver 8.0.12 for Linux on x86_64 (MySQL Community Server - GPL)
我在这台低配服务器上安装了数据库以及一个Spring Boot程序,我先启动数据库,启动成功了。再启动应用,发现应用连接不上数据库,于是去检查数据库。
发现数据库却提示启动失败。
发现问题第一步是去看日志,一般日志都会告诉你一些很有用的信息,让你更具体的了解到问题所在,而不是一出问题就胡乱复制一段到搜索引擎找答案。
用指令
cat /var/log/mysqld.log
查看MySQL日志,得到如下图信息,可以看到,分配InnoDB存储引擎缓冲池内存失败了,内存不足导致。
这里MySQL默认需要分配的内存太大了,我的机器性能不够,猜想可不可以设置一下,初始化一个比较小的内存空间。
搜索配置文件
find / -name my.cnf
注意,Windows环境下配置文件为my.ini
vi /etc/my.cnf
我把这个值改为了4M,数据库启动成功了。
但是事情还没有结束。
一般情况下,内存不够用的时候会发生什么?一般内存算法会把一些在内存里面很久不活动的文件暂时存到交换区,(更多关于内存、交换区的知识请查阅更多资料)而把马上就要进行处理的数据放到内存空间。
那么为什么在启动MySQL时会出现内存不足启动失败的情况呢?
于是查看一下交换区空间
free -m
Swap: 0 0 0
原来在系统创建的时候,没有分配交换区空间。
说明一下,这是一台我租的用于特殊用途的云服务器,预算有限所以配置比较低。哎,少花钱的代价就是要更折腾~
这下就知道对于当前环境下,最好的解决方案了:
由于外存是SSD(固态硬盘),所以相对于之前修改配置的方法,最好的办法是,给操作系统分配一段交换区空间!
分配一个4G大小的交换区空间
当然你可以根据你机器的情况来决定啦!我的内存比较小,所以分配大一些,避免再次出现“OutOfMemory”
如果物理内存比较大,实际上可以不分配交换区空间也可以,因为可能分配了却从来都用不上,反而造成资源浪费,这是一个需要琢磨的问题!但是一般最好还是分配一段,现在存储越来越廉价!
fallocate -l 4G /swapfile
现在已经分配好了一段空间,但是操作系统还不知道这一块是专门留给他用来做交换区的,所以还要告诉操作系统,但是在这之前,先设置一下这段空间的权限,设置root用户有读写的权限,其他用户没有任何权限。
Linux的权限控制很有意思,chmod是设置权限的指令,参数“600”,指分配给root用户读和写的权限,其他用户没有权限。在Linux里面 4代表读权限,2代表写权限,1代表执行权限,加起来就是某个用户拥有的权限,比如7就是拥有读和写和执行的权限。这是另一个话题,在这里不做扩展,扩展阅读《鸟哥的Linux私房菜》。
chmod 600 /swapfile
接下来是告诉操作系统,刚分配的这一块空间是交换区
mkswap /swapfile
至此已经完成,再检验一下
可以看到交换区空间已经分配完毕。
但是如上的配置,在系统重启之后,将不会保存,因此还需要将配置持久化:
编辑/etc/fstab文件,再末尾添加如下一行,再保存即可。
/swapfile swap swap sw 0 0