正在阅读:

解决MySQL经常停止运行(swap分区设置)

QQ截图20170828111212.jpg

背景

自从搭建了这个个人博客,MySQL就经常性的奔溃,前面写过一篇文章《记一次解决MySQL经常停止运行的问题》,在文章中对MySQl的错误日志进行了分析并对错误做出了相应的修改,不错,我去你大爷的,今天MySQL又崩了。。。不过这次的错误日志和上次的稍有差别。上次的报错对解决问题有了一点误导。这次的解决办法是添加Swap交换分区。

问题分析

下面是本次MySQL的报错日志:

170827 17:29:31 mysqld_safe Number of processes running now: 0
170827 17:29:31 mysqld_safe mysqld restarted
170827 17:29:32 InnoDB: Mutexes and rw_locks use GCC atomic builtins
170827 17:29:32 InnoDB: Compressed tables use zlib 1.2.3
170827 17:29:32 InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137363456 bytes) failed; errno 12
170827 17:29:32 InnoDB: Completed initialization of buffer pool
170827 17:29:32 InnoDB: Fatal error: cannot allocate memory for the buffer pool
170827 17:29:32 [ERROR] Plugin 'InnoDB' init function returned error.
170827 17:29:32 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
170827 17:29:32 [ERROR] Unknown/unsupported storage engine: InnoDB
170827 17:29:32 [ERROR] Aborting

和上篇文章中的日志想比,本次少了一句话:

170806 14:33:23 InnoDB: The InnoDB memory heap is disabled

所以说,这句报错并不是导致MySQL死掉的原因,所以我们的问题直接指向了内存上。从日志中可以看到在分配内存的时候出错了,报错error12,猜测可能是服务器内存上升后,MySQL启动的内存分配不够用了,导致MySQL启动失败。ok既然问题在这,那么下面就解决问题。

针对上面内存分配的问题,有一下几个方式可以解决方式:

1、增大服务器内存

2、增加或增大Swap交换分区

3、减小MySQL启动时的内存分配

增大服务器内存

what!增大服务器内存?没钱!老贵了。此法不行,下一位....

blob.png

添加Swap交换分区

哎呀,这个最靠谱了,这个可以有。Swap交换分区什么是?百度一下:Swap在Linux叫做交换分区,类似于Windows的虚拟内存,就是当内存不足的时候,把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。Swap,Swap好,Swap好啊!啥都别说,就是干!先看一下服务器的内存情况:


1
2
3
4
5
[root@kTWO ~]# free -h
             total       used       free     shared    buffers     cached
Mem:          996M       685M       310M       480K        98M       180M
-/+ buffers/cache:       407M       588M
Swap:           0B         0B         0B

这....这特么就尴尬了,Swap是0 0 0 ,之前买了服务器,没配置就直接用了,忘记设置Swap了。。。下面开始设置一下

分2G物理内存给Swap,这里大小一般根据实际内存而定,一般设置为实际内存的1-2倍,命令如下:


1
2
3
4
[root@kTWO var]#  dd if=/dev/zero of=/var/swap bs=1024 count=2048000
2048000+0 records in
2048000+0 records out
2097152000 bytes (2.1 GB) copied, 6.8837 s, 305 MB/s

dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。

if(inut file)后面/dev/zero代表输入文件是一个全不都是0的源文件,of(out file)是输出文件的位置,该命令常用来对文件进行初始化。

bs等同于同时设置ibs和obs(对应input、output),作为输入输出的缓冲区大小。

count用于限制从/dev/zero拷贝的块的数目,算起来swapfile的大小就是count * bs = 2GB。

下面的命令将文件变成swap分区


1
2
3
4
5
[root@kTWO var]# mkswap /var/swap
mkswap: /var/swap: warning: don't erase bootbits sectors
        on whole disk. Use -f to force.
Setting up swapspace version 1, size = 2047996 KiB
no label, UUID=84f3f540-213c-4816-85d9-7604e8be9824

开启Swap:


1
[root@kTWO var]# swapon /var/swap

查看Swap情况:


1
2
3
[root@kTWO var]# swapon -s
Filename                Type        Size    Used    Priority
/var/swap                               file     2047996 0   -1

查看内存情况:


1
2
3
4
5
[root@kTWO var]# free -h
             total       used       free     shared    buffers     cached
Mem:          996M       266M       729M       476K       2.1M        44M
-/+ buffers/cache:       220M       775M
Swap:         2.0G         0B       2.0G

可以看到,此时的Swap已经有了,不过used是0,这说明还没有用到,只有当内存使用比较大的情况下才会使用到Swap。

下面将Swap设置为开机启动:


1
[root@kTWO var]# vi /etc/fstab

在文件末尾添加下面一行:


1
/var/swap            swap                 swap       defaults              0 0

截图如下:

blob.png

到此为止Swap就设置好了。下面附上Swap的删除命令:


1
[root@kTWO var]# swapoff /var/swap

上面的命令关闭了Swap,然后删除/var/swap文件即可。

减少InnoDB buffer pool的内存占用

编辑MySQL的配置文件my.cnf,一般为止在/etc/my.cnf,在[mysqld]下面添加下面一行:

innodb_buffer_pool_size = 64M

如果之前改配置已经存在,直接修改后面的数字即可。这里我将内存分配修改为之前的一半了。

blob.png

留下脚印,证明你来过。

*

*

流汗坏笑撇嘴大兵流泪发呆抠鼻吓到偷笑得意呲牙亲亲疑问调皮可爱白眼难过愤怒惊讶鼓掌