Linux上跑MySQL优化技巧
1.禁止操作系统更新文件的atime属性
atime是Linux/UNIX系统下的一个文件属性,每当读取文件时,操作系统都会将读操作时间回写到磁盘上。对于读写频繁的数据库文件来说,记录文件的访问时间一般没有任何用处,却会增加磁盘系统的负担,影响I/O性能!因此,可以通过设置文件系统的mount熟悉,阻止操作系统写atime信息,减轻磁盘I/O负担。方法如下:
(1)修改文件系统配置文件/etc/fstab,指定noatime选项:
UUID=-e8a7--844f-707a5537e86a /data ext4 noatime
(2)重新mount文件系统使其修改生效:
[root@MySQL- ~]# mount -o remount /data
2.调整I/O调度算法
详细说明请参考前面文章提到的I/O调度算法的选择
(1)查看当前系统支持的I/O调度算法:
[root@MySQL- ~]# dmesg | grep -i scheduler
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
[root@MySQL- ~]#
(2)查看当前设备(/dev/sda)使用的I/O调度算法:
[root@MySQL- ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]
[root@MySQL- ~]#
(3)修改当前设备使用的I/O调度算法,普通磁盘可以选择Deadline,SSD我们可以选择使用NOOP或者Deadline
[root@MySQL- ~]# echo "deadline" >> /sys/block/sda/queue/scheduler
[root@MySQL- ~]# cat /sys/block/sda/queue/scheduler
noop anticipatory [deadline] cfq
[root@MySQL- ~]#
永久修改I/O调度算法,可以通过修改内核引导参数,增加elevator=调度算法名
[root@MySQL- ~]# vim /boot/grub/menu.lst
更改后的内容:
[root@MySQL- ~]# grep "deadline" /boot/grub/menu.lst
kernel /vmlinuz-2.6.-.el6.x86_64 ro root=UUID=c0618639-a967--bca7-cc3b99c5c332 elevator=deadline rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF- rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM
[root@MySQL- ~]#
3.NUMA架构优化
从系统架构来看,目前的商用服务器大体可以分为三类:
(1)对称多处理器架构(Symmetric Multi-Processor,SMP)
(2)非一致存储访问架构(Non-Uniform Memory Access,NUMA)
(3)海量并行处理架构(Massive Parallel Processing,MPP)
一般服务器是SMP或者NUMA架构的较多。我这里只详细说明NUMA架构,至于其他的童鞋们可以自行查阅资料^_^
NUMA把一台计算机分成多个节点(Node),每个节点内部拥有多个CPU,节点内部使用共有的内存控制器,节点之间是通过互联模块进行连接和信息交互,因此节点的所有内存对于本节点所有的CPU是等同的,而对于其他节点中的所有CPU都是不同的。因此每个CPU可以访问整个系统内存,但是访问本地节点的内存速度最快(不需要经过互联模块),访问非本地节点的内存速度较慢(需要经过互联模块),即CPU访问内存的速度与节点的距离有关,距离称为Node Distance。如下图:
显示当前NUMA的节点情况:
[root@localhost ~]# numactl --hardware
available: nodes (-)
node cpus:
node size: MB
node free: MB
node cpus:
node size: MB
node free: MB
node distances:
node
:
:
[root@localhost ~]# free -m
total used free shared buffers cached
Mem:
-/+ buffers/cache:
Swap:
[root@localhost ~]#
当前服务器上有两个节点Node 0和Node 1,Node 0的本地内存约为16GB,Node 1的本地内存约为16GB,可以看出系统一共有32GB内存
节点之间的距离(Node Distance)是指节点1访问节点0上的内存需要付出的代价的一种表现形式。在上述例子中,Linux节点本地内存声明距离为10,非本地内存声明距离20.
NUMA的内存分配策略分为以下4种:
(1)缺省default:总是在本地节点分配(分配在当前进程运行的节点上)
(2)绑定bind:强制分配到指定节点上
(3)交叉interleave:在所有节点或者指定节点上交叉分配内存
(4)优先preferred:在指定节点上分配,失败则在其他节点分配
显示当前系统NUMA策略:
[root@localhost ~]# numactl --show
policy: default
preferred node: current
physcpubind:
cpubind:
nodebind:
membind:
[root@localhost ~]#
因为NUMA默认的内存分配策略是优先在进程所在CPU的本地内存中分配,会导致CPU节点之间内存分配不均衡,当某个CPU节点内存不足时,会导致SWAP发生,而不是从远程节点分配内存,这就是Swap Insanity现象。
MySQL是单进程多线程架构的数据库,当NUMA采用默认的内存分配策略时,MySQL进程会被并且仅仅会被分配到NUMA的一个节点上去。假设MySQL进程被分配到Node 1运行,这个节点的本地内存是8GB,而MySQL配置了14GB内存,MySQL分配的14GB内存中,超过节点本地内存部分(14GB-8GB=6GB)Linux系统宁愿使用Swap也不会使用其他节点的物理内存。在这种情况下,能观察到系统虽然总共可用的物理内存还很多,但是MySQL进程已经开始使用Swap了。
MySQL对NUMA的特性支持不好,如果单机只运行一个MySQL实例,可以选择关闭NUMA,关闭的方式有两种:
(1)硬件层,在BIOS中设置关闭
(2)OS内核层,启动时设置numa=off
修改/etc/grub.conf,添加numa=off
[root@MySQL- ~]# vim /etc/grub.conf
[root@MySQL- ~]# grep 'numa' /etc/grub.conf
kernel /vmlinuz-2.6.-.el6.x86_64 ro root=UUID=c0618639-a967--bca7-cc3b99c5c332 elevator=deadline rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF- rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM numa=off
[root@MySQL- ~]#
或者通过numactl命令将NUMA的内存分配策略修改为interleave
/usr/bin/numactl --interleave=all /usr/local/mysql-5.1./bin/mysqld_safe --defaults-file=/usr/local/mysql-5.1./my.cnf
这样就指定了MySQL启动时内存的分配策略是interleave
如果单机运行多个MySQL实例,可以将不同MySQL实例绑定到不同的CPU节点上,同时配置合适的MySQL内存参数,并且采用绑定的内存分配测试,强制在本地节点分配内存。
4.vm.swappiness调整
swappiness是操作系统控制物理内存交换出去的策略。它允许的值是一个百分比的值,最小为0,最大运行100,该值默认为60。vm.swappiness设置为0表示尽量少swap,100表示尽量将inactive的内存页交换出去。
具体的说:当内存基本用满的时候,系统会根据这个参数来判断是把内存中很少用到的inactive 内存交换出去,还是释放数据的cache。cache中缓存着从磁盘读出来的数据,根据程序的局部性原理,这些数据有可能在接下来又要被读取;inactive 内存顾名思义,就是那些被应用程序映射着,但是“长时间”不用的内存。
我们可以利用vmstat看到inactive的内存的数量:
[root@MySQL- ~]# vmstat -an
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st [root@MySQL- ~]#
通过/proc/meminfo 你可以看到更详细的信息:
[root@MySQL- ~]# cat /proc/meminfo | grep -i inact
Inactive: kB
Inactive(anon): kB
Inactive(file): kB
[root@MySQL- ~]#
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中添加一行(如果你的内核版本是2.6.32-303.el6及以后,请设置vm.swappiness = 1):
[root@MySQL- ~]# echo "vm.swappiness = 0" >>/etc/sysctl.conf
[root@MySQL- ~]# sysctl -p
另外一种做法是innodb启用大内存页,也和上述方法有相同的效果。具体请参考前面文章提到的InnoDB启用大内存页。
5.CPU优化
检查CPU是否开启了节能选项
[root@localhost ~]# grep -E '^model name|^cpu MHz' /proc/cpuinfo
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
model name : Intel(R) Xeon(R) CPU L5520 @ .27GHz
cpu MHz : 2266.602
[root@localhost ~]#
for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n performance > $CPUFREQ; done
节能模式:操作系统和CPU硬件配合,系统不繁忙的时候,为了节约电能和降低温度,它会将CPU降频。对MySQL来说,可能是一个灾难。 为了保证MySQL能够充分利用CPU的资源,建议设置CPU为最大性能模式。这个设置可以在BIOS和操作系统中设置,当然,在BIOS中设置该选项更好。
参考资料:
http://www.mysqlperformanceblog.com/2013/12/07/linux-performance-tuning-tips-mysql/
http://www.benjaminathawes.com/2011/11/09/determining-numa-node-boundaries-for-modern-cpus/
http://dikar.iteye.com/blog/776563
Linux上跑MySQL优化技巧的更多相关文章
- sqlyog连接Linux上的mysql报错误号码2013,错误号码1130的解决办法
sqlyog连接Linux上的mysql报错误号码2013,错误号码1130的解决办法 1.报错误号码2013,可能是端口号不是默认的3306,需要改成对应的,检查命令是: [root@host et ...
- Python3.7.2,在Linux上跑来跑去的,是在升级打怪么?
Python3.7.2,在Linux上跑来跑去的,是在升级打怪么? 前不久,发布了Python在Windows(程序员:Python学不学?完全没必要纠结)和Mac OS(我是Python,P派第 ...
- 怎样在 Ubuntu Linux 上安装 MySQL
本教程教你如何在基于 Ubuntu 的 Linux 发行版上安装 MySQL.对于首次使用的用户,你将会学习到如何验证你的安装和第一次怎样去连接 MySQL. -- Sergiu MySQL 是一个典 ...
- Linux上通过MySQL命令访问MySQL数据库时常见问题汇总
Linux上通过mysql命令访问MySQL数据库时常见问题汇总 1)创建登录账号 #创建用户并授权 #允许本地访问 create user 'test'@'localhost' identified ...
- 【数据库开发】在Windows上和Linux上配置MySQL的过程
[数据库开发]在Windows上和Linux上配置MySQL的过程 标签(空格分隔): [编程开发] 首先是在Windows上尝试用QT进行MySQL数据库开发,结果总出现driver不能load的错 ...
- linux上安装 mysql
一.linux 上安装 mysql 1.查看mysql是否安装 rpm -qa|grep mysql 2.卸载 mysql yum remove mysql mysql-server mysql-li ...
- 让asp.net和php同时在Linux上跑起来
实现这个想法有很多种方法,我就我最近算是比较熟悉的方式来说给大家吧. 因为有了mono,所以.net才能跨平台,.net都跨平台了,.net平台的童鞋们是不是应该提起精神好好了解下mono呢? 当然了 ...
- Linux上跑两个版本的php,5.4.45和5.3.24
首先,装的实在艰难,所以容我吐槽两句: PHP好个P,两个小版本都不兼容,把这个php5.3.24放在5.4.45环境下都跑不了.对于我这种用多了向下兼容的java的人来说,简直无法想象! 网上有装俩 ...
- MySQL优化技巧
目录 MySQL的特点 数据类型优化 整型类型 小数类型 字符串类型 时间类型 主键类型的选择 特殊类型的数据 索引优化 一个使用Hash值创建索引的技巧 前缀索引 多列索引 聚簇索引 覆盖索引 重复 ...
随机推荐
- (实用)CentOS 6.3更新内置Python2.6
在安装Kilo版的OpenStack时,我们发现社区已经将Python升到2.7,而CentOS 6.3上仍然在使用2.6版的Python.本文记录将CentOS 6.3内置的Python2.6更新为 ...
- 为何谷歌围棋AI AlphaGo可能会把李世石击溃
/* 版权声明:可以随意转载,转载时请标明文章原始出处和作者信息 .*/ author: 张俊林 谷歌DeepMind开发的人工智能围棋程序AlphaGo以5:0的压倒性优势击败了欧洲围棋冠军.专业二 ...
- 如何在Ubuntu 16.04上安装配置Redis
如何在Ubuntu 16.04上安装配置Redis Redis是一个内存中的键值存储,以其灵活性,性能和广泛的语言支持而闻名.在本指南中,我们将演示如何在Ubuntu 16.04服务器上安装和配置Re ...
- 【netcore基础】MVC API接口权限控制Attribute
效果: 通过Attribute来简单控制某个方法的访问权限 例如: 下面api只能角色id是[001,002,999]的登录用户才能访问 /// <summary> /// 管理用户列表 ...
- play mp3 in c#
using System; using System.Runtime.InteropServices; using System.Text; using System.IO; using System ...
- Maven使用deploy上传jar包到远程库
一.环境准备 首先需要在本地环境安装好maven,并且在环境变量配置好 二.配置远程库认证 需要在./conf/setting.xml(maven的配置文件,不要弄错)中配置需要远程上传库的地址,用户 ...
- AngularJS快速教程
作者:arccosxy 转载请注明出处:http://www.cnblogs.com/arccosxy/ AngularJS是Google开源的一款JavaScript MVC前端框架,弥补了HTM ...
- Asp.NET调用有道翻译API
调用有道API进行翻译,如图: HTML: <%@ Page Language="C#" AutoEventWireup="true" CodeFile= ...
- JavaScript外部函数调用AngularJS的函数、$scope
x 场景: 需要在用FusionCharts画的柱状图中添加点击事件,But弹出框是Angularjs搞的,我想的是直接跳到弹出框的那个路由里,然后在弹出框的控制器中绑定数据即可: /* 点击事件 * ...
- Haproxy的三种保持客户端会话保持方式
2017-03-25 15:41:41 haproxy 三种保持客户端Seesion; 一.源地址hash(用户IP识别) haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类 ...