我对 pg_stat_replication view 的write_location和flush_location感到困惑。文档说, write_location 代表最后一个事务日志位置被这个备用服务器写入磁盘, flush_location 代表最后一个事务日志位置被这个备用服务器刷新到磁盘,有什么区别吗?
在主数据库上查询 pg_stat_replication 视图
sent_location : Last transaction log position sent on this connection
write_location: Last transaction log position written to disk by this standby server
flush_location: Last transaction log position flushed to disk by this standby server
replay_location: Last transaction log position replayed into the database on this standby server
postgres=# select * from pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
pid | 23453
usesysid | 24619
usename | repuser
application_name | node1
client_addr | 192.168.2.37
client_hostname |
client_port | 58412
backend_start | 2015-09-07 20:56:13.141438+08
backend_xmin |
state | streaming
sent_location | 2/3D397B1C
write_location | 2/3D397B1C
flush_location | 2/3D397B1C
replay_location | 2/3D390954
sync_priority | 1
sync_state | sync
pg_stat_replication 中的两列基本上是指出
write(2)
和之间的区别fsync(2)
从
write(2)
联机帮助页:从
fsync(2)
手册页:默认情况下,在正常操作下,PostgreSQL 会调用 fsync(或 fdatasync,如果你在 linux 上),以确保 WAL 段中的数据正确且真实地写入磁盘。
在正常操作中,当发生写入调用时,它基本上是将该数据从 PostgreSQL 复制到文件系统缓存,这只是另一位 RAM。如果服务器崩溃,那么您仍然会丢失该数据,因为它仍在 RAM 中,即使它只是 RAM 的不同部分。
但是,在 上
COMMIT
,PostgreSQL 调用fsync
,它强制将 WAL 段数据写出到磁盘,而不仅仅是写入 RAM 中的文件系统缓存。这确保在崩溃后,提交的数据仍然提交,并且可以重放。它还具有需要
fsync
为数据文件调用更少次数的额外优势,因为正确重播对这些文件的更改所需的所有数据都包含在 WAL 段中,这些段持久保存在磁盘中。可以在文章Flushing Disk Buffers中找到对 Linux 下此行为的一个很好的描述。
可以使用wal_sync_method和fsync控制同步行为
希望这有助于回答您的问题。=)