(本文阅读预计时间:17分钟)
文章转载自公众号:PostgreSQL学徒
作者:熊灿灿
PostgreSQL中的流复制是一种成熟的主从复制技术。设置简单、稳定、性能好。许多人在了解复制冲突时都感到惊讶,毕竟备用服务器是只读的。本文描述复制冲突并告诉您如何处理它们。 一、什么是复制冲突 每当恢复进程无法在备用服务器上应用从主服务器传递过来的WAL信息时,就会发生复制冲突,因为变更会中断正在执行的查询。这些冲突不会在主服务器上的查询中发生,但会在流复制中的备用服务器上发生,因为主服务器对备用服务器上发生的事情知之甚少。 二、有几种复制冲突 (一)快照复制冲突 这是最常见的复制冲突。如果VACUUM处理一个表并且删除了死元组,可能会发生快照冲突。这一删除的动作也会在备用服务器上重放。备用服务器上的查询可能已经在主服务器上的VACUUM发生之前启动(它有一个较早的快照),因此它仍然可以看到应该删除的元组。这变会构成快照冲突。 (二)锁复制冲突 在备用服务器上,对正在执行查询的表上,获得了ACCESS EXCLUSIVE的排他锁。因此,必须在备用服务器上回放主服务器上的任何获取ACCESS EXCLUSIVE锁的操作(与ACCESS SHARE冲突),以防止发生表上不兼容的操作。PostgreSQL在诸如DROP TABLE,TRUNCATE和大多数ALTER TABLE等操作会获取与SELECT相冲突的锁,如果备用服务器在正在查询使用的表上回放这样的锁,就会发生锁冲突。 (三)Buffer pin replication conflicts One way to reduce the need for VACUUM is to use HOT updates. Then any query on the primary that accesses a page with dead heap-only tuples and can get an exclusive lock on it will prune the HOT chains. PostgreSQL always holds such page locks for a short time, so there is no conflict with processing on the primary. There are other causes for page locks, but this is perhaps the most frequent one.When the standby server should replay such an exclusive page lock and a query is using the page (“has the page pinned” in PostgreSQL jargon), you get a buffer pin replication conflict. Pages can be pinned for a while, for example during a sequential scan of a table on the outer side of a nested loop join.HOT chain pruning can of course also lead to snapshot replication conflicts. 减少对VACUUM需求的一种方法便是使用HOT更新。 然后,任何在主数据库上访问具有仅堆堆已死的元组的页面并且可以对其进行独占锁定的查询都将修剪HOT链。然后,任何在主数据库上访问仅包含死堆元组的页面并可以在该页面上获取exclusive锁的查询都将修剪HOT链。PostgreSQL总是在很短的时间内持有这种页面锁,因此与主数据库上的处理没有冲突。页面锁定还有其他原