PostgreSQL Replication之第四章 设置异步复制(7)

4.7 冲突管理

在PostgreSQL中,流复制数据仅在一个方向流动。XLOG由master提供给几个slave,这些slave消耗事务日志并为您提供一个较好的数据备份。您可能想知道这怎么会导致冲突,这会发生冲突。

考虑一下情形:如您所知,数据复制有很小的延迟。因此,XLOG在由master产生之后结束于slave。这微小的延迟会引起如下图所示的情景:

PostgreSQL Replication之第四章 设置异步复制(7)

我们假设一个slave开始读取一个表。它是一个长读操作。与此同时,master收到一个请求,实际地删除那个表。这有一点问题,因为slave仍然需要这个数据来执行它的SELECT语句。另一方面,所有来自master的请求任何情况下必须被服从。这是一个经典的冲突。

[如果发生冲突,PostgreSQL将发出一下错误信息:由于恢复冲突终止连接。]

有两种选择来解决这个问题:

1. slave终止有问题的操作之前,不要重放冲突的事务日志

2.杀死slave上的查询来解决那个问题。

第一选择在回放进程回放期间可能会导致严重的延迟,尤其是当slave执行相当长的操作。第二个选择可能经常杀死slave上的查询。数据库实例不能通过自己知道对您的应用程序什么是最好的。所以您必须要在延迟重放和杀死查询之间找到一个适当的平衡。

为了找到这个微妙的平衡,PostgreSQL在postgresql.conf中提供了两个参数:

max_standby_archive_delay = 30s

# max delay before canceling queries

# when reading WAL from archive;

# -1 allows indefinite delay

max_standby_streaming_delay = 30s

# max delay before canceling queries

# when reading streaming WAL;

# -1 allows indefinite delay

当有冲突操作的时候,max_standby_archive_delay 参数会告诉系统,终止XLOG重放需要多长时间。在默认设置中, 如果找到一个冲突,slave将推迟XLOG重放长达30s 。如果slave 正在从文件重放事务日志,这个设置是有效的。

如果XLOG正在通过流进入slave,max_standby_streaming_delay 会告诉slave ,终止XLOG重放需要多长时间。如果时间已经到期,并且冲突仍然存在,PostgreSQL 将取消那个语句,因为一个恢复问题引起slave系统上的问题,恢复XLOG恢复来追赶。

在前面的例子中,我们已经表明,如果一个表被删除,冲突可能会出现。这是一个明显的场景;然而,迄今为止,它还不是最常见的一个。它更可能是一行通过VACUUM或HOT-UPDATE来删除,导致slave上的冲突。

冲突一段时间冒出来一次很烦人,并引发您的应用产生不良行为。换句话说,如果可能的话,冲突应该避免。我们已经看到了重放日志是如何延迟的。这些并不是PostgreSQL提供的唯一机制。还有两个我们可以使用的设置。

两个设置中的第一个同时也是较早的设置是vacuum_defer_cleanup_age。它在事务中被测量并告诉PostgreSQL什么时候删除一行数据。通常如果没有更多的事务可以看到数据,一行数据通过VACUUM被删除。vacuum_defer_cleanup_age告诉VACUUM不立即清除一行数据,但是在数据被清除之前会等待一些事务。

推迟清理将保持一行数据的时间比需要的时间稍长。这有助于slave完成那些依靠旧数据行的查询。尤其是如果您的slave提供处理一些分析工作的服务,这将有助于确保没有查询白白的杀死。

还有一个控制冲突的方法是利用hot_standby_feedback。这个想法是slave向master报告事务ID,这也可以反过来,使用此信息来推迟VACUUM。这是避免slave上的清理冲突的最简单的方法之一。

[请记住,延迟清理会导致增加空间占用及一些副作用,在任何情况下都必须牢记。其效果和在master上运行长事务一样。]

上一篇:js的class属性获取、增加、移除


下一篇:PMP 第二章 项目生命周期与组织