概述

为了保证数据可靠性,同时还要保证好的读写性能,以及读写的一致性,经过多年的积累,REDO日志,shared buffer等基本成为关系型数据库的标配。postgres也不例外。

为了保证数据的可靠性,通常在将脏页面写入硬盘前,先将wal日志先写入硬盘,然后将修改的数据异步分批写入。

为了保证好的读写性能,修改的数据先写到shared buffer中,而不是直接写入硬盘,因为数据页很离散(修改的数据分布在不同的表中)。数据库会把wal日志顺序写入硬盘中。

postgres提供两种方式写:write和fsync。区别是:

write:数据库会将buffer中的脏页根据写入策略将老化的脏页面写到OS,OS再根据自己的调度算法将脏页写入硬盘。
fsync:数据库直接调用OS的fsync函数,直接写入硬盘。

OS层面

涉及到几个内核参数,同时还涉及到文件系统。

dirty_background_ratio

设置方法

1、修改systctl:vm.dirty_background_ratio
2、修改文件/proc/sys/vm/dirty_background_ratio

含义

在尝试执行writeback操作(即OS触发background flush线程刷脏页)之前内存脏页面比例。
控制文件系统的pdflush进程,在何时刷新磁盘。
单位是百分比,当写缓冲使用到系统内存多少时,pdflush开始向磁盘写出数据。
增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。
但当需要持续、恒定的写入场合时,应该降低其数值。缺省值5。

dirty_expire_centisecs

设置方法

1、修改systctl:vm.dirty_writeback_centisecs
2、修改文件/proc/sys/vm/dirty_expire_centisecs

含义

background flush线程将存活时间超过该值的脏页刷盘(类似LRU)。
数据可以保持为dirty状态的最大时间,超过该值pdflush进程就开始考虑写到磁盘中去。
单位是1/100s。缺省30000,也就是30s。
对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。
建议设置为1500,也就是15秒算旧。

dirty_ratio

设置方法

1、修改systctl:vm.dirty_ratio
2、修改文件/proc/sys/vm/dirty_ratio

含义

控制文件系统的文件系统写缓冲区的大小,单位是百分比。
当脏页比例达到该值,用户进程在调用write时,会触发flush磁盘的操作。表示当写缓冲使用到系统内存多少时,开始向磁盘写出数据。
当一个任务(或者进程)在脏页面过多的环境中执行文件写操作时,如果脏页面占用总内存的百分比高于dirty_ratio值,那么系统就执行脏页面写入硬盘操作。
增大会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。
但当需要持续、恒定的写入场合时,应该降低其数值,缺省值10。

dirty_writeback_centisecs

设置方法

1、修改systctl:vm.dirty_writeback_centisecs
2、修改文件/proc/sys/vm/dirty_writeback_centisecs

含义

控制内核的脏数据刷新进程pdflush的运行间隔,执行background flush线程的唤醒间隔。
单位是1/100s。缺省值是500,也就是5s。
适当减少该值有写操作削峰作用,如果系统是持续地写入动作,那么降低该值比较好,可以把尖峰写操作削平成多次写操作。
该参数值应小于dirty_expire_centisecs,但太小I/O太频繁,反而使系统性能下降。
据说1:6 (dirty_expire_centisecs: dirty_writeback_centisecs )的比例比较好。

dirty_background_bytes

如果内存非常大,当触发后台线程刷脏页时,可能需要刷很多脏页,导致尖锐的IO需求。

可以通过修改内核参数vm.dirtybackgroundbytes达到削尖的目的。

vm.dirtybackgroundbytes
= 102400000 当脏页数达到了100MB,系统触发background flush线程刷脏页

数据库层面

wal日志写入方式fsync

fsync = on
开启后强制把wal日志同步更新到磁盘,可以保证数据库将在OS或者硬件崩溃的后恢复到一个一致的状态。
虽然关闭,可以提升数据库性能,但无法保证数据库崩溃后数据一致性。
通常情况下需要打开这个参数,除非能经受掉电或硬件故障带来的数据丢失,否则不要关闭。

backend_flush_after

单位:BLCKSZ
当某backend process脏数据超过配置阈值时,触发调用OS sync_file_range,告诉os backend flush线程异步刷盘。
从而削减os dirty page堆积。

bgwriter_flush_after

单位:BLCKSZ
当bgwriter process脏数据超过配置阈值时,触发调用OS sync_file_range,告诉os backend flush线程异步刷盘。
从而削减os dirty page堆积。

checkpoint_flush_after

单位:BLCKSZ
当checkpointer process脏数据超过配置阈值时,触发调用OS sync_file_range,告诉os backend flush线程异步刷盘。
从而削减os dirty page堆积。

wal_writer_flush_after

单位:BLCKSZ
当wal writer process脏数据超过配置阈值时,触发调用OS sync_file_range,告诉os backend flush线程异步刷盘。
从而削减os dirty page堆积。

Postgres间隔大量写IO的解决办法的更多相关文章

  1. Android HttpURLConnection.connect找不到源 HttpURLConnection连接失败 HttpURLConnection.connect IO异常 解决办法

    Android HttpURLConnection.connect找不到源  HttpURLConnection连接失败 HttpURLConnection.connect IO异常 解决办法 以下代 ...

  2. Delphi7程序调用C#写的DLL解决办法(转)

    近来,因工作需要,必须解决Delphi7写的主程序调用C#写的dll的问题.在网上一番搜索,又经过种种试验,最终证明有以下两种方法可行:    编写C#dll的方法都一样,首先在vs2005中创建一个 ...

  3. Delphi7程序调用C#写的DLL解决办法

     近来,因工作需要,必须解决Delphi7写的主程序调用C#写的dll的问题.在网上一番搜索,又经过种种试验,最终证明有以下两种方法可行:    编写C#dll的方法都一样,首先在vs2005中创建一 ...

  4. python中导入模块的本质, 无法导入手写模块的解决办法

    最近身边一些朋友发生在项目当中编写自己模块,导入的时候无法导入的问题. 下面我来分享一下关于python中导入模块的一些基本知识. 1 导入模块时寻找路径 在每一个运行的python程序当中,都维护了 ...

  5. 需要序列化的类中没有写serialVersionUID的解决办法

    由于没赋值serialVersionUID 只是警告,不是错误,造成先前没留意设定serialVersionUID,网络两端上线运行一段时间也感觉正常.如果再增减修改field,没赋值好serialV ...

  6. [C#]使用 C# 代码实现拓扑排序 dotNet Core WEB程序使用 Nginx反向代理 C#里面获得应用程序的当前路径 关于Nginx设置端口号,在Asp.net 获取不到的,解决办法 .Net程序员 初学Ubuntu ,配置Nignix 夜深了,写了个JQuery的省市区三级级联效果

    [C#]使用 C# 代码实现拓扑排序   目录 0.参考资料 1.介绍 2.原理 3.实现 4.深度优先搜索实现 回到顶部 0.参考资料 尊重他人的劳动成果,贴上参考的资料地址,本文仅作学习记录之用. ...

  7. kafka启动时出现FATAL Fatal error during KafkaServer startup. Prepare to shutdown (kafka.server.KafkaServer) java.io.IOException: Permission denied错误解决办法(图文详解)

    首先,说明,我kafk的server.properties是 kafka的server.properties配置文件参考示范(图文详解)(多种方式) 问题详情 然后,我启动时,出现如下 [hadoop ...

  8. li 与 li 之间有空白间隔是什么原因引起的,有什么解决办法

    li 与 li 之间有空白间隔是什么原因引起的,有什么解决办法 原因 浏览器会把inline元素间的空白字符(空格.换行.Tab等)渲染成一个空格.而为了美观,我们通常是一个 放在一行,这导致 换行后 ...

  9. 块级标签包含行内标签底部出现3px间隔的解决办法

    当块级标签(如div)内包含了行内标签(如img),则外层元素与内层元素底部会出现3px的间隔: 代码如下: <!doctype html> <html lang="en& ...

随机推荐

  1. strtok的用法(文件操作)

    strtok :在一个字符串查找下一个符号 char *strtok( char *strToken, const char *strDelimit ); 返回值:返回指向在strToken字符串找到 ...

  2. ZOJ-2753

    Min Cut (Destroy Trade Net) Time Limit: 15 Seconds      Memory Limit: 32768 KB Given an undirected g ...

  3. Merge Intervals——STL的应用

    Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8, ...

  4. Matlab处理数据导出Paraview可读的vtk文件(二)

    由于我在用SPH方法仿真时用的是FORTRAN语言,并且没有找到直接输出vtk文件的代码,因此偷懒通过MATLAB转换一下数据. 用到的Matlab子程序可通过一下链接找到. Matlab处理数据导出 ...

  5. JS获取 KindEditor textarea 标签 html内容失败的解决方法。

    KindEditor 这个 东西 研究的不多,JS在通过调用getElementById 获取文本id的内容时候,KindEditor 尚未将内容同步,官方给的解决方法是afterBlur: func ...

  6. [你必须知道的.NET]第二十五回:认识元数据和IL(中)

    发布日期:2009.02.25 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 书接上回[第二十四回:认识元数据和IL(上)], ...

  7. java程序中如何为一个while(true)循环计时,超过一定时间比如10个小时就退出循环?

    public void execute(int hour){ long t1 = System.currentTimeMillis(); while(true){ long t2 = System.c ...

  8. MediaPlayer滑动不准的问题

    因为MediaPlayer在seekto是异步进行的,如果在滑动过程中暂停,会导致滑动不准确的情况,这时候就需要添加滑动完成的监听即setOnSeekCompleteListener

  9. 关于sql查询语句中的别名

    sql语句中给子查询或其他查询类型加别名的时候可能会报错 java.sql.SQLException: 无法转换为内部表示 原因是select返回类型的实体类中没有写该别名 原来的实体类 更改后的实体 ...

  10. Luogu P3258 松鼠的新家(树链剖分+线段树/树状数组)

    题面 题解 这种题目一看就是重链剖分裸题,还是区间修改,单点查询,查询之前在遍历时要记一个\(delta\),因为这一次的起点就是上一次的终点,不需要放糖,所以可以用\(BIT\)来写,但我写完\(m ...