fsync (boolean)
如果打开这个参数,PostgreSQL服务器将尝试确保更新被物理地写入到磁盘,做法是发出fsync()系统调用或者使用多种等价的方法(见wal_sync_method)。
这保证了数据库集簇在一次操作系统或者硬件崩溃后能恢复到一个一致的状态。
虽然关闭fsync常常可以得到性能上的收益,但当发生断电或系统崩溃时可能造成不可恢复的数据损坏。
因此,只有在能很容易地从外部数据中重建整个数据库时才建议关闭fsync。
能安全关闭fsync的环境的例子包括从一个备份文件中初始加载一个新数据库集簇、使用一个数据库集簇来在数据库被删掉并重建之后处理一批数据,
或者一个被经常重建并却不用于失效备援的只读数据库克隆。单独的高质量硬件不足以成为关闭fsync的理由。
当把fsync从关闭改成打开时,为了可靠的恢复,需要强制在内核中的所有被修改的缓冲区进入持久化存储。这可以在多个时机来完成:
在集簇被关闭时或在 fsync 因为运行initdb –sync-only而打开时、运行sync时、卸载文件系统时或者重启服务器时。
在很多情况下,为不重要的事务关闭synchronous_commit可以提供很多关闭fsync的潜在性能收益,并不会有的同时, 关闭fsync可以提供很多潜在的性能优势,
而不会有伴随着的数据损坏风险。
fsync只能在postgresql.conf文件中或在服务器命令行上设置。如果你关闭这个参数,请也考虑关闭full_page_writes。
synchronous_commit (enum)
指定在命令返回”success”指示给客户端之前,一个事务是否需要等待 WAL 记录被写入磁盘。合法的值是on、remote_write、local 和 off。
默认的并且安全的设置是on。当设置为off时,在向客户端报告成功和真正保证事务不会被服务器崩溃威胁之间会有延迟(最大的延迟是wal_writer_delay的三倍)。
不同于fsync,将这个参数设置为off不会产生数据库不一致性的风险:一个操作系统或数据库崩溃可能会造成一些最近据说已提交的事务丢失,但数据库状态是一致的,
就像这些事务已经被干净地中止。因此,当性能比完全确保事务的持久性更重要时,关闭synchronous_commit可以作为一个有效的代替手段。更多讨论见第 30.3 节。
如果synchronous_standby_names被设置,这个参数也控制事务提交是否将等待事务的 WAL 记录被复制到后备服务器上。当这个参数被设置为on时,
直到来自于当前同步的后备服务器的一个回复指示该后备服务器已经收到了事务的提交记录并将其刷入了磁盘,主服务器上的事务才会提交。这保证事务将不会被丢失,
除非主服务器和后备服务器都遭受到了数据库存储损坏的问题。当这个参数被设置为remote_write时,提交将等待,直到来自当前同步的后备服务器的一个回复指示该服务器
已经收到了该事务的提交记录并且已经把该记录写出到后备服务器的操作系统,但是该数据并不一定到达了后备服务器上的稳定存储。这种设置足以保证数据在后备服务器的
PostgreSQL实例崩溃时得以保存,但是不能保证后备服务器遭受操作系统级别崩溃时数据能被保持。
当使用同步复制时,它将对等待本地刷写磁盘和 WAL 记录复制很敏感,或者对允许事务异步提交很敏感。不过,设置local可以用于希望等待本地刷写磁盘但不等待同步复制的事务。
如果没有设置synchronous_standby_names,设置on、remote_write和local都提供了同样的同步级别:事务提交只等待本地刷写磁盘。
这个参数可以随时被修改;任何一个事务的行为由其提交时生效的设置决定。因此,可以同步提交一些事务,同时异步提交其他事务。例如,当默认是相反时,
实现一个单一多语句事务的异步提交,在事务中发出SET LOCAL synchronous_commit TO OFF。
下面做个实验看下
mondb=# d tmp_wal_compress
Table "public.tmp_wal_compress"
Column | Type | Modifiers
-------------+-----------------------+-----------
id | bigint |
random_char | character varying(50) |
random_int | bigint |
#####################################################
mondb=# truncate table tmp_wal_compress;
TRUNCATE TABLE
Time: 3.429 ms
mondb=# select name,setting from pg_settings ps where ps.name in ('synchronous_commit','fsync');
name | setting
--------------------+---------
fsync | on
synchronous_commit | on
(2 rows)
Time: 2.484 ms
mondb=# insert into tmp_wal_compress select generate_series(1, 10000000) as id, md5(random()::text) as info ,trunc(random()*10000000)
mondb-# ;
INSERT 0 10000000
Time: 48370.781 ms
#####################################################
mondb=# truncate table tmp_wal_compress;
TRUNCATE TABLE
Time: 39.273 ms
mondb=# select name,setting from pg_settings ps where ps.name in ('synchronous_commit','fsync');
name | setting
--------------------+---------
fsync | off
synchronous_commit | on
Time: 2.484 ms
mondb=# insert into tmp_wal_compress select generate_series(1, 10000000) as id, md5(random()::text) as info ,trunc(random()*10000000)
mondb-# ;
INSERT 0 10000000
Time: 40566.090 ms
#####################################################
mondb=# truncate table tmp_wal_compress;
TRUNCATE TABLE
Time: 3.429 ms
mondb=# select name,setting from pg_settings ps where ps.name in ('synchronous_commit','fsync');
name | setting
--------------------+---------
fsync | on
synchronous_commit | off
(2 rows)
Time: 2.559 ms
mondb=# insert into tmp_wal_compress select generate_series(1, 10000000) as id, md5(random()::text) as info ,trunc(random()*10000000)
;
INSERT 0 10000000
Time: 43026.087 ms
#####################################################
mondb=# truncate table tmp_wal_compress;
TRUNCATE TABLE
Time: 9.112 ms
mondb=# select name,setting from pg_settings ps where ps.name in ('synchronous_commit','fsync');
name | setting
--------------------+---------
fsync | off
synchronous_commit | off
(2 rows)
Time: 2.559 ms
mondb=# insert into tmp_wal_compress select generate_series(1, 10000000) as id, md5(random()::text) as info ,trunc(random()*10000000)
;
INSERT 0 10000000
Time: 40418.334 ms
通过简单实验可以看出
fsync 由 on 设置为 off 时,性能有大概 15% 的提升。虽然性能提高了,但是风险加大了。
synchronous_commit 由 on 设置为 off 时,性能提升并不是特别明显。