同步复制9/2010议案
目录 [隐藏]
1 PAGE状态 2 有何不同之处这个补丁? 3 同步复制概述 4 用户视角 4.1 管理员视角 5 实现 5.1 STANDBY 5.2 MASTER 6 CODE 7 性能分析 8 尚未实现 9 ,其他问题
PAGE状态
此页面可以作为一个同步复制文件的由西蒙·里格斯在2010年9月公布。 请注意,这个建议是不是该结束了正在实施的版本有所不同: 见更多的细节。
这个补丁有何不同之处?
在9.1的实现包括一些创新,超越了提供的PostgreSQL的9.0较早的同步复制实现:
- 备机状态代码的复杂度低
- 用户控制:所有决定等待发挥主的地方,让同步复制的细粒度控制。最大复制级别也可以在待机设置。
- 低带宽:非常小的响应数据包的大小与响应的数量没有增加,当系统处于高负载下意味着只需要很少的额外带宽
- 性能:待机过程中同时工作给予的待机和最小的延迟良好的整体吞吐量在所有模式。4个性能选择不相互干扰,所以提供彼此并排不同级别的性能/耐久性。 这些都是重要的PostgreSQL的项目之上基本同步rep 功能的优越之处。
同步复制概述
同步复制提供了一个交易的所有变化都被转移到远程备用节点的保证。这是一个扩展,由事务提交提供耐用的水准水平。 当需要同步复制的事务等待它提交后,直到接收确认转会已经成功。等待确认增加了用户的肯定,转移已经发生,但它也必然增加的响应时间请求交易。同步复制通常需要精心策划,并放置备用服务器,以确保应用程序执行得体。等待期间不利用系统资源,但事务锁继续被保持到传送已被确认。其结果是,不谨慎使用同步复制会导致对数据库应用程序性能降低。 它可能看起来有耐用性和性能之间的简单的选择。然而,往往是数据的重要性,以及如何繁忙的数据库需要之间有密切的关系,所以这是很少一个简单的选择。有了这个补丁,现在的PostgreSQL提供了一系列的设计,让应用程序架构师设计出既具有良好的综合性能和最重要的数据资产尚未耐久性优异的系统功能。 PostgreSQL允许应用程序设计者指定通过复制所需的耐用性水平。这可以为系统规定的总的,虽然它也可以为个别交易指定。这允许有选择地为关键数据提供保护的最高水平。 例如,我们,一个应用程序可能包括两种类型的工作:
- 10%的变化的为重要的客户信息
- 90%的变化是,如果丢失,如用户之间的聊天消息业务可以更容易地生存不太重要的数据。
随着在应用程序级别(在主站)指定的同步复制选项,我们可以提供最重要的变化同步代表,而不会减慢了大部分的总工作量的。应用级选项允许同步复制的高性能应用的利益的重要而实用的工具。 如果没有在应用程序级别指定的同步选项代表,我们将不得不要么减慢90%的工作量,因为它10%是重要的选择。或放弃,因为我们的表现耐久性目标。或拆分这两个函数到不同的数据库服务器,使我们可以在不同的每个设置的选项。这些3个选项都不是真正的吸引力。 PostgreSQL的还允许系统管理员指定由备用服务器所提供的服务水平的能力。这允许多个备用服务器到服务器场中的各种角色一起工作。
注意:有关参数此处使用的信息反映与该功能的较早版本,并且需要被更新,以反映它被提交到9.1的形式 此功能的控制依赖于刚3个参数:在主机(Master)上,我们可以设置
- synchronous_replication
- synchronous_replication_timeout
在备机状态下,我们可以设置
- synchronous_replication_service
这些更详细地在下面的章节中说明。
用户视角
在主控制两个新USERSET这个参数
-
synchronous_replication =async (default)| recv | fsync | apply
-
synchronous_replication_timeout = 0+(0表示永不超时) (默认超时10秒) synchronous_replication =async 是缺省值,意味着没有synchronisaton要求,因此,提交将不会等待。这是最快的设置。这个词异步是短期的“异步”,你可能会看到这个词异步复制讨论。 其他设置是指逐步更高水平的耐久性。耐久性的要求的水平越高,要达到的更长的等待耐久性的这一水平。 的synchronous_replication设置的确切含义是
-
async - 提交不等待备备机回复用户之前
-
recv - 直到备用收到WAL提交等待
-
fsync - 直到备用收到并fsynced WAL提交等待
-
apply - 直至待机已收到,fsynced 和应用提交等待
这提供了一个简单的,容易理解的机制 - 与一个在其默认的形式是非常相似的其他RDBMS(如Oracle)。 请注意,在应用模式下,它是可能的变化可能是上所做的更改已通知该变化是完成交易前的待机访问。 (小问题)。 可能会出现网络延迟和待机也可能会崩溃。如果没有答复我们提出一个注意的超时时间内接收,然后返回成功提交(没有其他的行动是可能的)。注意,有可能请求我们从未超时,因此,如果没有备用可用我们等待它之一出现。 当用户提交,如果主没有一个当前连接的备用复制提供所要求的水平,将挑选复制的下一个最好的水平。它是由系统管理员提供足够的范围备用节点的,以确保至少有一个是可用的,以满足所请求的服务水平。 如果存在多个备用,第一待机回复耐久性已经实现将释放等待理想的水平上的主提交。其他选项也可以通过一个插件。
管理员视角
在待机状态下,我们指定的最高类型由该备用服务器提供复制服务。此信息被传递到主服务器时备用复制连接。 这使得系统管理员将首选备用。它还允许系统管理员完全拒绝提供同步复制服务,让主明确地避免在低带宽和高延迟链路同步。
一个附加的参数可在的recovery.conf被设置在备用
synchronous_replication_service =async(def)| recv | fsync | apply
实现
某些方面可以在不改变显著基本提案进行修改,例如主指定的备机不会真正改变这一非常多。
备机
主控制同步代表处意味着所有用户等待逻辑上的主中心。在主同步请求代表的细节不会被发送到备用,所以没有额外的主人待机流量也不待机侧簿记开销。它还减少的待机代码的复杂性。 在待机方面现在WAL作家恢复过程中运行。这将释放WALReceiver花更多的时间发送和接收消息,从而为用户选择“接收”选项,最小的系统延迟。我们现在有3个进程中的异步处理管线WAL:WAL接收来自libpq的连接读取WAL数据然后再写入WAL文件时,WALWriterfsync() 写入的WAL文件,然后启动过程中重播WAL。这些程序独立行事,所以WAL指针(的LSN)被定义为WALReceiverLSN> = WALWriterLSN> = StartupLSN 对于每一个新的消息WALReceiver从高手指点,我们予以答复。每个应答发送3的LSN的当前状态,因此,应答消息大小只有28字节。将回复发送半双工的,即当有新邮件到达,我们不回复。 需要注意的是绝对不是在主服务器上每个事务一份答复。待机一无所知什么已被要求在主 - 回复总是指最新的待机状态,有效地批量的响应。 我们根据所请求的synchronous_replication_service充当
- async - 不发送答复
- recv - 答复在收到仅发送
- fsync - 答复在收到发送,只有以下FSYNC
- apply - 回复发送到以下回执,FSYNC和应用。
回复是在下次有机会时发送。
在apply模式下,当WALReceiver是完全安静,这意味着我们发送3回复消息
- 分别在recv的,一个在fsync,一个在apply。 当WALreceiver忙不不不能,直到已收到目前收到的消息,之后我们要去反正回复,所以它不是一个额外的消息中发送的消息量,因为回复增长。这意味着我们在捎带“应用”响应到后来的“接收”的答复。 因此,我们得到所有的模式,最大吞吐量完全不受损最小的响应时间。
当每个新的消息从主机到达WALreceiver将写入新的数据到WAL文件,唤醒WALwriter,然后答复。 从主每一个新的消息,收到了答复。 如果已经接收任何进一步的WAL数据WALreceiver等待上的闩锁。 如果WALReceiver被WALWriter或启动唤醒,然后将回复到主与消息,即使没有新的WAL已经收到。 因此,在这两个recv的,FSYNC并尽快申请个案信息掌握, 所以在所有情况下的等待时间最小化。 当WALwriter被唤醒时它认为, 如果有优秀的WAL数据,如果是这样fsync作业数据唤醒既WALreceiver和启动。 如果没有WAL仍然等待门闩。 启动过程中会醒WALreceiver时,它已经得到了WAL的最新块的结束。 如果没有进一步的WAL可用,则等待其锁定。
主
当用户请求后端同步代表他们等待在所要求LSN有序的队列。有一条单独队列为每个请求模式。 WALSender从待机接收3的LSN。然后,它唤醒,从每个队列顺序后端。 我们提供了一个单一的唤醒规则: 第一WALSender与请求XLogRecPtr答复将唤醒后端。 这保证了对提交的WAL数据的请求到至少一个备用被传送。这是足够的,我们已经讨论了用例。 更复杂的唤醒规则将通过插件是可能的(More complex wakeup rules would be possible via a plugin.)。 等待超时会被个别后端具有定时设置,就像我们的statement_timeout所做的一样。
代码CODE
总代码来实现是比较简单的(原文 low )。分解成5个区域
- Zoltan的libpq的变化,包括几乎一字不差; 相当模块化,这样方便的东西来代替,我们更喜欢
- 一个新的模块syncrep.c和syncrep.h处理后台等待/唤醒
- 轻量的变化,使流媒体代表进行适当的调用
- 代码量小,让WALWriter是在积极的恢复
- 参数代码
没有文档呢(笔者翻译时已经有了)。
** 该补丁构建于闩锁(Latch)之上,虽然对于其传输的Bulk的性能特性不依赖于它们。 插销仅提高响应时间非常低的事务处理速度; 在中高频率的高频事物交易之上,锁存器提供没有额外的吞吐量,不能保证中高频事物。**
(The patch works on top of latches, though does not rely upon them for its bulk performance characteristics.
- Latches only improve response time for very low transaction rates;
- latches provide no additional throughput for medium to high transaction rates.)
性能分析
因为我们回复主机发送每一个新的块, “接收”模式具有绝对最小的延迟, 特别是因为WALreceiver不再执行大多数fsync()写入,如在9.0代码。 WALreceiver不会等待FSYNC或应用操作来完成我们的回答之前, 因此FSYNC和应用模式会一直等待至少2 standby->掌握的消息, 因为这些行为会通常会出现晚得多这是合适的。 这种反应机制提供了“接收”模式和负荷下很好的吞吐量达到最高响应性能。 注意不同的模式不相互干扰,并且可以共存愉快,同时提供最高的性能。
开始WALWriter是有帮助的,不管指定什么 synchronous_replication_service
。 我们可以优化回复消息的发送,以便只包含一个提交块应该有一个答复? 我们可以,但我们需要做的主额外的工作做的簿记。 这将需要证明存在性能问题大到足以值得在主人和额外代码的开销。 有没有从降低待机提供的选项数的优化? 在备用侧的结构并不在很大程度上依赖于所指定的服务水平, 也不依赖于对主指定的实际同步代表模式的任何方式。
没有进一步的简化是可能的。
尚未实现
超时代码与注意事项 代码和测试插件 在循环walsender,walwriter和接收器治疗不当关机 我还没有看藤井代码这一点,甚至不知道它在哪里,但希望在未来这么做。佐尔坦的libpq的代码是使用补丁的一部分。 到目前为止,我已经花了此3.5天,预计完成的明天。我认为,抛出这个建议太复杂在此版本中开发的论点。 其他事宜
如何应掌握的行为,当我们关闭它? 应该如何循规蹈矩待机,当我们关闭它?