PostgreSQL 的基于流复制的物理备库是基于wal日志的物理块复制备库,允许开放只读的功能,但是由于主库可能不断的产生wal,这些wal可能会与备库的QUERY产生冲突。
简单点来说,就是查询(query)与恢复(备库apply)冲突。
可能出现冲突的情况?
1、例如主库truncate a 表,备库查询a表。
2、主库删除表空间,备库使用这个表空间产生临时文件。例如主库删除TBS,备库的一个大的查询需要写临时文件,并且这个临时文件是写到这个表空间的。
3、主库在回收dead tuple的REDO, 同时备库当前的query snapshot需要看到这些记录。
注:这种情况可以通过参数控制,恢复优先,或查询优先。可以配置时间窗口。这种冲突的出现的概率不大,除非是用户在备库使用repeatalbe read,同时是非常大的事务。
4、当query访问的页就是要清理垃圾的页时。
如何避免或者降低冲突?
1、在主库配置Vacuum_defer_cleanup_age
2、在备库配置recovery延迟来解决以上所有冲突,给备库的Query设置一个执行窗口。
max_standby_achive_delay
max_standby_streaming_delay
3、在备库配置hot_standby_feedback, 备考会将备库的xmin反馈给上游,从而主库知道备库还需要哪些记录,在cleanup dead tuple时,会考虑备库的情况,防止冲突。
hot_stanndby_feedback
参考:https://github.com/digoal/blog/blob/master/201608/20160815_03.md