背 景
PostgreSQL 的基于流复制的物理备库是基于redo的物理块复制备库,允许开放只读的功能,但是需要注意,由于主库可能不断的产生redo,这些redo可能会与备库的QUERY产生冲突。
什么情况下query会堵塞、或与恢复冲突?
当以下操作产生的REDO被复制到备库,并且备库准备拿这些REDO来恢复时。
-
Access Exclusive locks taken on the primary server, including both explicit LOCK commands and various DDL actions, conflict with table accesses in standby queries.
主库的访问排它锁,与备库对应的锁产生冲突。
例如主库truncate a表, 备库查询a表。
这种情况的冲突面很窄。
-
Dropping a tablespace on the primary conflicts with standby queries using that tablespace for temporary work files.
主库删除表空间,备库使用这个表空间产生临时文件。 例如主库删除TBS,备库的一个大的查询需要写临时文件,并且这个临时文件是写到这个表空间的。
这种情况非常少见,也很容易规避,新建一个临时表空间不要删除即可。
-
Dropping a database on the primary conflicts with sessions connected to that database on the standby.
主库删除数据库,备库刚好连在这个数据库上。
这种情况也非常的少见。
-
Application of a vacuum cleanup record from WAL conflicts with standby transactions whose snapshots can still "see" any of the rows to be removed.
主库回收dead tuple的REDO,同事备库当前的query snapshot需要看到这些记录。
这种情况可以通过参数控制,恢复优先,或查询优先。 可以配置时间窗口。
而且这种冲突出现的概率也非常的小,除非用户在备库使用repeatable read,同时是非常大的事务。
而通常用户用的都是read committed。
-
Application of a vacuum cleanup record from WAL conflicts with queries accessing the target page on the standby, whether or not the data to be removed is visible.
同上,但是当query访问的页就是要清理垃圾的页时,也是有冲突的。 这是物理复制与逻辑复制唯一有差别的地方,但是对现实场景来说,这种情况出现的概率也不大。
案 例
最近收到了一个冲突的例子,是这样的,在备库查询一些函数,导致了这样的报错。
|