PostgreSQL之background writer

background writer进程是什么

background writer进程是将共享内存中的脏页写入磁盘的进程。

在对数据进行处理之前都需要将数据从磁盘读到内存中,更新完毕后再将修改的数据写回磁盘,在postgresql中由backgroud writer与server process负责将“脏“数据写回磁盘。

大致过程是这样的:

先由backgroud writer进程进行写,剩余的数据再由server process进程完成

background writer进程的相关参数

background writer在postgresql.conf中有一个专门的部分来配置它的行为

# - Background Writer -

#bgwriter_delay = 200ms                 # 10-10000ms between rounds
#bgwriter_lru_maxpages = 100            # max buffers written/round, 0 disables
#bgwriter_lru_multiplier = 2.0          # 0-10.0 multiplier on buffers scanned/round
#bgwriter_flush_after = 512kB           # measured in pages, 0 disables

bgwriter_delay

backgroud writer进程连续两次flush数据之间的时间的间隔。默认值是200,单位是毫秒。

bgwriter_lru_maxpages

backgroud writer进程每次写的最大数据量,默认值是100,单位buffers。如果脏数据量小于该数值,写操作全部由backgroud writer进程完成;反之,大于该值时,大于的部分将由server process进程完成。设置该值为0时表示禁用backgroud writer写进程,完全由server process来完成;配置为-1时表示所有脏数据都由backgroud writer来完成。(这里不包括checkpoint操作)

bgwriter_lru_multiplier

此参数指示了每次写入磁盘的数据块数,当然,该值必须小于bgwriter_lru_maxpages。如果设置过小,需要写入的脏数据量大于每次写入的数据量,剩下的需要写入磁盘的工作,就需要server processes来完成,这将会降低性能。如果值配置太大,此时写入的脏数据量就会超过所需的缓冲区数量,这虽然便于以后再次应用缓冲区工作,但同时可能会出现IO浪费。这个参数的默认值是2.0。bgwriter的最大数据量计算方式:
1000/bgwriter_delay*bgwriter_lru_maxpages*8K=最大数据量
上述参数对于数据文件所在磁盘的带宽也很有参考意义

参数值依据系统状态而设置,通过监控系统的运行状况,进行分析总结,为参数配置合适的值。参考数据字典pg_stat_bgwriter。

postgres=# d pg_stat_bgwriter
                        View "pg_catalog.pg_stat_bgwriter"
        Column         |           Type           | Collation | Nullable | Default
-----------------------+--------------------------+-----------+----------+---------
 checkpoints_timed     | bigint                   |           |          |
 checkpoints_req       | bigint                   |           |          |
 checkpoint_write_time | double precision         |           |          |
 checkpoint_sync_time  | double precision         |           |          |
 buffers_checkpoint    | bigint                   |           |          |
 buffers_clean         | bigint                   |           |          |
 maxwritten_clean      | bigint                   |           |          |
 buffers_backend       | bigint                   |           |          |
 buffers_backend_fsync | bigint                   |           |          |
 buffers_alloc         | bigint                   |           |          |
 stats_reset           | timestamp with time zone |           |          |

postgres=# SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed, pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req, pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint, pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean, pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean, pg_stat_get_buf_written_backend() AS buffers_backend, pg_stat_get_buf_alloc() AS buffers_alloc;
 checkpoints_timed | checkpoints_req | buffers_checkpoint | buffers_clean | maxwritten_clean | buffers_backend | buffers_alloc
-------------------+-----------------+--------------------+---------------+------------------+-----------------+---------------
590 |               3 |                  3 |             0 |                0 |               0 |           226
(1 row)

bgwriter_flush_after

当数据页大小达到bgwriter_flush_after时触发BgWriter,默认值为512KB。

为什么需要background writer

postgresql中脏数据的写入不仅仅是由backgroud writer参数决定的,checkpoint也对脏数据的写入进行了控制。

backgroud writer进程的间隔是以毫秒计算,而checkpoint的间隔时间相对要很长。所以bgwriter更像是在checkpoint的周期内去完成脏数据的写入。所以bgwriter进程如果能够实现周期均匀数据量合适的写入数据,减少IO的次数,对checkpoint也能够减轻压力,不至于发生集中的写入操作,而造成IO使用的高值,可以说backgroud writer间接使系统的IO负载趋于稳定。

原文地址:https://www.cnblogs.com/mingfan/p/13967084.html