1.方法1: 打开 noatime
每个文件上都有以下上个时间:
ctime: 改变时间
mtime: 修改时间
atime: 访问时间
通常Postgresql 并不使用这三个时间;
首先禁止的是:atime
mtime 和 ctime 有时还有些作用
设置 noatime 如下:vim /etc/fstab
/dev/sdd1 / xfs noatime,errors=remount-ro 0 1
2.方法2: 调整预读
Linux 下块设备通常都默认打开了预读,可以使用下面的命令查看预读的大小:
blockdev --getra /dev/sdf
注意,上面的命令中值的单位为扇区,即 512bytes. 在下面的示例中:
sudo blockdev --getra /dev/sda
返回值为256,表示是256个扇区,即为128KB
设置预读的命令如下:
blockdev --setra 4096 /dev/sdf
上面的设置并不会永久生效,机器重启后就会失效,如果想要永久生效,应该
把命令放到自动脚本中
如果想让全表扫描更快一些,可以把预读调整大一些,如像上例那样把预读设置为2MB
3.方法3:调整虚拟内存参数
需要调整的第一个参数是 swappiness
为0的时候尽量使用物理内存,值越大,越倾向于使用swap空间,
默认值是 60 查看方法:
cat /proc/sys/vm/swappiness
设置此参数值,并使其永久生效的方法是在 /etc/sysctl.conf 添加如下行:
wm.swappiness = 0
然后执行 sysctl -p 让配置生效
如果想让PosrgreSQl的数据库性能尽量稳定平稳,就应该把此值设置为0
需要调整第二个参数是 overcommit.
在linux 中 调用malloc() 函数分配内存时,只会分配虚拟内存,真正的物理内存没有被分配,只有进程真正需要使用时,才会分配,这种技术叫 overcommit
vm.overcommit 参数可控制调用 malloc() 函数时分配内存的行为,可取三个值:
0 : 启发式策略,表示liunx 将启发式的检查是否有足够内存可以Overcommit 如果有则调用malloc() 成功,内存申请成功,否则,内存申请失败,并发错误返回给应用程序。
1:调用malloc() 总是成功,并不管当前的内存实际情况
2:不允许overcommit,即当分配给所有进程的内存超过 swapd大小+%N *物理时,会分配失败
N%是一个百分比,这个值由另一个参数 vm.overcommit_ratio 来控制的
0和1 都不能避免 OOMkiller
把此参数设置 2
vm.overcommit_memory=2
你如果像保守一点,可以将 vm.overcommit_ratio = 0
你也可以根据机器的中物理内存和swap空间大小进行合理配置
4. 方法4:写缓存优化
在linux系统中,对于文件的普通写并不会尼玛体现到磁盘中,而是先写道内存页Cache上,
实际摔下来到磁盘中是由内核线程来完成的。在2.6的内核下这个内核线程为pdflush,3.0则为
flush进程
在Linux系统中,有以下上个参数用于控制写缓存的过程:
1.vm.dirty_background_ratio: 指定了文件系统中缓存脏页数量达到系统内存的 百分之多少 时(如5%),就会触发内核刷新脏页线程,从而将一定缓存的脏页异步刷新到磁盘。
2.vm.dirty_ratio: 指定了文件系统中缓存脏页数量达到系统内存的 百分之多少 时,(如10%),系统不得不把缓存脏页写入餐盘中,此过程可能导致很多应用进程的文件IO被阻塞
3.vm.dirty_writeback_centisece:单位为百分之一秒,指定内核线程执行刷脏页的回写操作之间的时间间隔。
linux 内核中, vm.dirty_background_ratio 为10,vm.dirty_ratio 为40,这显然太大了。
在较新的内核中,这两个参数的默认值做了如下修改:
vm.dirty_background_ratio = 10
vm.dirty_ratio =20
在较大的内存的机器上,可以把这两个值调低一些,具体根据需求来定,可以通过测试来确定更准确的值。
5.方法5:调整IO调度器
linux 下通常有一下三种I/O调度器:
1.CFQ: completely fair queuing,完全公平队列,尝试为所有的请求分配公平的I/O带宽,注意时带宽,而不是响应时间
2.deadline: 平衡所有的请求,避免某个请求被饿死,让响应时间最优化
3.noop: 除了基本的块合并及排序工作,其他基本里上什么都不做。
可以看出,数据库比较适合使用 deadline调度器,而linux默认时CFQ,手工设置调度器的方法如下:
echo deadline > /sys/block/sdd/queue/scheduler
真实配置时,上面中的"add" ,需要换成实际的硬盘名称
另一种方法就是 修改grub.conf中的启动命令行,在命令行上加上: elevator=deadline
如下:
kernel /vmlinuz-2.6.18-128.e15 ro root=/dev/sda1 elevator = deadline
改变I/O调度器,对postgresql性能提升很小,所以保留默认的调度器也是可以的