LINUX上MYSQL优化三板斧

如今MySQL运行的大部分环境都是在Linux上的,如何在Linux操做系统上根据MySQL进行优化,咱们这里给出一些通用简单的策略。这些方法都有助于改进MySQL的性能。node

闲话少说,进入正题。mysql

1、CPU

首先从CPU提及。sql

你仔细检查的话,有些服务器上会有的一个有趣的现象:你cat /proc/cpuinfo时,会发现CPU的频率居然跟它标称的频率不同:数据库

#cat /proc/cpuinfo processor : 5model name : Intel(R) Xeon(R) CPU E5-2620 0 @2.00GHz ...cpu MHz : 1200.000

这个是Intel E5-2620的CPU,他是2.00G * 24的CPU,可是,咱们发现第5颗CPU的频率为1.2G。 缓存

这是什么缘由呢?安全

这些其实都源于CPU最新的技术:节能模式。操做系统和CPU硬件配合,系统不繁忙的时候,为了节约电能和下降温度,它会将CPU降频。这对环保人士和抵制地球变暖来讲是一个福音,可是对MySQL来讲,多是一个灾难。服务器

为了保证MySQL可以充分利用CPU的资源,建议设置CPU为最大性能模式。这个设置能够在BIOS和操做系统中设置,固然,在BIOS中设置该选项更好,更完全。因为各类BIOS类型的区别,设置为CPU为最大性能模式千差万别,咱们这里就不具体展现怎么设置了。架构

2、内存

而后咱们看看内存方面,咱们有哪些能够优化的。app

i) 咱们先看看numa

非一致存储访问结构 (NUMA : Non-Uniform Memory Access) 也是最新的内存管理技术。它和对称多处理器结构 (SMP : Symmetric Multi-Processor) 是对应的。简单的队别以下:性能

如图所示,详细的NUMA信息咱们这里不介绍了。可是咱们能够直观的看到:SMP访问内存的都是代价都是同样的;可是在NUMA架构下,本地内存的访问和非 本地内存的访问代价是不同的。对应的根据这个特性,操做系统上,咱们能够设置进程的内存分配方式。目前支持的方式包括:

--interleave=nodes--membind=nodes--cpunodebind=nodes--physcpubind=cpus--localalloc--preferred=node

简而言之,就是说,你能够指定内存在本地分配,在某几个CPU节点分配或者轮询分配。除非 是设置为--interleave=nodes轮询分配方式,即内存能够在任意NUMA节点上分配这种方式之外。其余的方式就算其余NUMA节点上还有内 存剩余,Linux也不会把剩余的内存分配给这个进程,而是采用SWAP的方式来得到内存。有经验的系统管理员或者DBA都知道SWAP致使的数据库性能 降低有多么坑爹。 

因此最简单的方法,仍是关闭掉这个特性。

关闭特性的方法,分别有:能够从BIOS,操做系统,启动进程时临时关闭这个特性。

a) 因为各类BIOS类型的区别,如何关闭NUMA千差万别,咱们这里就不具体展现怎么设置了。

b) 在操做系统中关闭,能够直接在/etc/grub.conf的kernel行最后添加numa=off,以下所示:

 
  1. kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/VolGroup-root
    rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=VolGroup/root rd_NO_MD quiet
    SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto rd_LVM_LV=VolGroup/swap
    rhgb crashkernel=auto quiet KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off  

另外能够设置 vm.zone_reclaim_mode=0尽可能回收内存。

c) 启动MySQL的时候,关闭NUMA特性:

numactl --interleave=all  mysqld &

固然,最好的方式是在BIOS中关闭。

ii) 咱们再看看vm.swappiness。

vm.swappiness是操做系统控制物理内存交换出去的策略。它容许的值是一个百分比的值,最小为0,最大运行100,该值默认为60。vm.swappiness设置为0表示尽可能少swap,100表示尽可能将inactive的内存页交换出去。

具体的说:当内存基本用满的时候,系统会根据这个参数来判断是把内存中不多用到的inactive 内存交换出去,仍是释放数据的cache。cache中缓存着从磁盘读出来的数据,根据程序的局部性原理,这些数据有可能在接下来又要被读 取;inactive 内存顾名思义,就是那些被应用程序映射着,可是“长时间”不用的内存。

咱们能够利用vmstat看到inactive的内存的数量:

#vmstat -an 1  procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----  r b swpd free  inact  active si so bi bo in cs us sy id wa st  1 0 0 27522384 326928 1704644 0 0 0 153 11 10 0 0 100 0 0  0 0 0 27523300 326936 1704164 0 0 0 74 784 590 0 0 100 0 0  0 0 0 27523656 326936 1704692 0 0 8 8 439 1686 0 0 100 0 0  0 0 0 27524300 326916 1703412 0 0 4 52 198 262 0 0 100 0 0

经过/proc/meminfo 你能够看到更详细的信息:

#cat /proc/meminfo | grep -i inact  Inactive: 326972 kB  Inactive(anon): 248 kB  Inactive(file): 326724 kB

这里咱们对不活跃inactive内存进一步深刻讨论。 Linux中,内存可能处于三种状态:free,active和inactive。众所周知,Linux Kernel在内部维护了不少LRU列表用来管理内存,好比LRU_INACTIVE_ANON, LRU_ACTIVE_ANON, LRU_INACTIVE_FILE , LRU_ACTIVE_FILE, LRU_UNEVICTABLE。其中LRU_INACTIVE_ANON, LRU_ACTIVE_ANON用来管理匿名页,LRU_INACTIVE_FILE , LRU_ACTIVE_FILE用来管理page caches页缓存。系统内核会根据内存页的访问状况,不定时的将活跃active内存被移到inactive列表中,这些inactive的内存能够被 交换到swap中去。

通常来讲,MySQL,特别是InnoDB管理内存缓存,它占用的内存比较多,不常常访问的内存也会很多,这些内存若是被Linux错误的交换出去了,将 浪费不少CPU和IO资源。 InnoDB本身管理缓存,cache的文件数据来讲占用了内存,对InnoDB几乎没有任何好处。

因此,咱们在MySQL的服务器上最好设置vm.swappiness=0。

咱们能够经过在sysctl.conf中添加一行:

echo "vm.swappiness = 0" >>/etc/sysctl.conf

并使用sysctl -p来使得该参数生效。

3、文件系统

最后,咱们看一下文件系统的优化

i) 咱们建议在文件系统的mount参数上加上noatime,nobarrier两个选项。

用noatime mount的话,文件系统在程序访问对应的文件或者文件夹时,不会更新对应的access time。通常来讲,Linux会给文件记录了三个时间,change time, modify time和access time。

咱们能够经过stat来查看文件的三个时间:

stat libnids-1.16.tar.gz  File: `libnids-1.16.tar.gz'  Size: 72309 Blocks: 152 IO Block: 4096 regular file  Device: 302h/770d Inode: 4113144 Links: 1  Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)   Access  : 2008-05-27 15:13:03.000000000 +0800  Modify: 2004-03-10 12:25:09.000000000 +0800  Change: 2008-05-27 14:18:18.000000000 +0800

其中access time指文件最后一次被读取的时间,modify time指的是文件的文本内容最后发生变化的时间,change time指的是文件的inode最后发生变化(好比位置、用户属性、组属性等)的时间。通常来讲,文件都是读多写少,并且咱们也不多关心某一个文件最近什 么时间被访问了。

因此,咱们建议采用noatime选项,这样文件系统不记录access time,避免浪费资源。

如今的不少文件系统会在数据提交时强制底层设备刷新cache,避免数据丢失,称之为write barriers。可是,其实咱们数据库服务器底层存储设备要么采用RAID卡,RAID卡自己的电池能够掉电保护;要么采用Flash卡,它也有自我保 护机制,保证数据不会丢失。因此咱们能够安全的使用nobarrier挂载文件系统。设置方法以下:

对于ext3, ext4和 reiserfs文件系统能够在mount时指定barrier=0;对于xfs能够指定nobarrier选项。 

ii) 文件系统上还有一个提升IO的优化万能钥匙,那就是deadline。

在 Flash技术以前,咱们都是使用机械磁盘存储数据的,机械磁盘的寻道时间是影响它速度的最重要因素,直接致使它的每秒可作的IO(IOPS)很是有限, 为了尽可能排序和合并多个请求,以达到一次寻道可以知足屡次IO请求的目的,Linux文件系统设计了多种IO调度策略,已适用各类场景和存储设备。

Linux的IO调度策略包括:Deadline scheduler,Anticipatory scheduler,Completely Fair Queuing(CFQ),NOOP。每种调度策略的详细调度方式咱们这里不详细描述,这里咱们主要介绍CFQ和Deadline,CFQ是Linux内 核2.6.18以后的默认调度策略,它声称对每个 IO 请求都是公平的,这种调度策略对大部分应用都是适用的。可是若是数据库有两个请求,一个请求3次IO,一个请求10000次IO,因为绝对公平,3次IO 的这个请求都须要跟其余10000个IO请求竞争,可能要等待上千个IO完成才能返回,致使它的响应时间很是慢。而且若是在处理的过程当中,又有不少IO请 求陆续发送过来,部分IO请求甚至可能一直没法获得调度被“饿死”。而deadline兼顾到一个请求不会在队列中等待过久致使饿死,对数据库这种应用来 说更加适用。

实时设置,咱们能够经过

echo deadline >/sys/block/sda/queue/scheduler

来将sda的调度策略设置为deadline。

咱们也能够直接在/etc/grub.conf的kernel行最后添加elevator=deadline来永久生效。 

总结

CPU方面:

关闭电源保护模式

内存: 

vm.swappiness = 0 

关闭numa

文件系统:

用noatime,nobarrier挂载系统

IO调度策略修改成deadline。

相关文章
相关标签/搜索