checkpoints are occurring too frequently

Background Writer (bgwriter)

功能:
负责定时写 shared buffer cache 中的 dirty shared buffers
好处:
a. 减少系统flush shared buffers到硬盘(已经被bgwriter做了)
b. 在checkpoint中,不会看到I/O的突然性暴增,因为dirty buffers在背景中已经被flush进硬盘
坏处:
因为一直定时在背后flush disk,会看到平均硬盘I/O怎加(好过checkpoint时I/O暴增)

设定:

bgwriter_delay:
sleep between rounds。 default 200(根据机器,数据而调整)

bgwriter_lru_maxpages:
决 定每次bgwriter写多少数据。如果实际数据大于这里的设定,那么剩余数据将会被postgres的进程(server process)来完成。server porcess自己写的数据会造成一定的性能下降。如果想确定所有的数据都由bgwriter来写,可以设定这里的值为-1

bgwriter_lru_multiplier:
采 用计算的方式来决定多少数据应该被bgwriter来写。这里保持内置的2.0就可以。

计算bgwriter的I/O:
1000 / bgwriter_delay * bgwriter_lru_maxpages * 8192 = 实际I/O
(8192是 postgres的8k block)
例如:
1000/200 * 100 * 8192 = 4096000 = 4000 kb

bgwrater 可以用 pg_stat_bgwriter 来监测。如果想要观察bgwrater 的运行状况,记得首先清理旧的stat信息。

bgwriter如果设定的太大(做太多事情)那么就会影响到前台的效能 (server)但是如果由系统(server)来做buffer flush同样会影响效能。所以这里的最好设定就是通过观察 pg_stat_bgwriter 来找到一个最佳的平衡点。
WAL (write ahead log)

postgres中的所有写动作都是首先写入WAL,然后才执行的。这样可以确保数据的准确跟 完整。当中途数据库崩溃的时候,postgres可以通过WAL恢复到崩溃前的状况而不会出现数据错误等等问题。
WAL 会在两种情况下被回写硬盘。
1. commit。 当commit数据的时候,WAL会被强制写回硬盘(flush)并且所有这个commit之前的东西如果在WAL中,也会一同被flush。
2. WAL writer进程自己会定时回写。

FSYNC vs ASYNC
postgres 的 default 是做 fsync,也就是说postgres会等待数据被写入硬盘,才会给query返回成功的信号。如果设定sync=no关闭fsync的话,postgres不会等待WAL会写硬盘,就直接返回query成功。通常这个会带来15-25%的性能提升。
但是缺点就是,如果系统崩溃 (断电,postgres挂掉)的时候,你将有可能丢失最后那个transcation. 不过这个并不会造成你系统的数据结构问题。(no data corrupt)如果说在系统出问 题的时候丢失1-2笔数据是可以接受的,那么25%的性能提升是很可观的。

WAL设定:
fsync 可以选择on或者off
wal_sync_method:
linux中是使用fdatasync。其他的。。。不知道,应该是看系统的文 件参数了
full_page_writes:
开启的时候,在checkpoint之后的第一次对page的更改,postgres会将每 个disk page写入WAL。这样可以防止系统当机(断电)的时候,page刚好只有被写一半。打开这个选项可以保证page image的完整性。
关 闭的时候会有一定的性能增加。尤其使用带电池的 RAID卡的时候,危险更低。这个选项属于底风险换取性能的选项,可以关闭

wal_buffers:
WAL 的储存大小。default 是 64 kb。 实验证明, 设定这个值在 256 kb 到 1 MB 之间会提升效能。

wal_writer_delay
WAL 检查WAL数据(回写)的间隔时间。值是毫秒(milliseconds)
Checkpoints

确保数据回写硬盘。dirty data page会被 flushed回硬盘。
checkpoint 由以下3中条件激发 (bgwriter如果设定,会帮忙在后台写入,所以就不会有checkpoint时候的短期高I/O出现)
1. 到达设定的WAL segments
2. 到达设定的timeout
3. 用户下达checkpoint指令
如果 checkpoint运行频率高于checkpint_warning值。postgres会在日志(log)中记录出来,通过观察log,可以来决定 checkpoint_segments的设定。
增加cehckpoint_segments或者checkpoint_timeout可以有一 定的效能提升。而唯一的坏处就是如果系统挂了,在重启的时需要多一点时间来回复(系统启动回复期间数据库是不能用的)鉴于postgres很少挂掉,这个 其实可以设定的很长(1天都可以)

设定:
checkpoint_segments 最多的wal log数量,到达后会激发checkpoint,通常设定在30就好
checkpoint_timeout 一般设置15-20分钟,常的可以设定1天也没关系
checkpoint_completion_target 这个保持不动就好。内建是0.5,意思就是每个checkpoint预计在下个checkpoint完成前的一半时间内完成(听起来有点绕嘴,呵呵)
checkpoint_warning 如果checkpint速度快于这个时间,在log中记录。内建是30秒

理论中的完美设定,就是你的backend从来不用回写硬盘。 东西都是由background来写入的。这个就要靠调整bgwriter, checkpoints跟wal到一个最佳平衡状态。当然这个是理想中的完美,想真的做到。。。继续想吧。呵呵

posted @ 2013-04-22 11:05  立春了  Views(814)  Comments(0Edit  收藏  举报