问题:在热备模式下,在从属设备上应用WAL更新(从属角色是报告数据库服务器)时,是否可以运行长时间运行的查询(30秒+)?它现在的工作方式是,要么设置下面的参数来杀死长时间运行的查询,以便可以应用WAL更新,或者无限期地延迟WAL更新,直到没有运行任何查询来应用它们。我们可以同时拥有吗?长时间运行的查询和WAL更新同时应用?
案例实施:我们目前正在使用热备模式同步从一个主服务器到一个服务器的任何更改。 slave角色是一个报告数据库服务器,其查询不断并同时运行(有些以ms为单位,有些以秒为单位, 一些在几分钟内。)在奴隶上运行没有活动查询的差距是非常罕见的。
我们调整了这两个参数,以便在热备用上进行长时间查询:
max_standby_archive_delay = -1 # max delay before canceling queries
max_standby_streaming_delay = -1 # max delay before canceling queries
在postgres邮件列表中查看与我们类似的存档邮件问题:
http://www.postgresql.org/message-id/AANLkTinLg+bpzcjzdndsnGGNFC=D1OsVh+hKb85A-s=n@mail.gmail.com
我理解阻止应用WAL更新的概念 查询运行时的从站。但是,我想过使用MVCC, 从站上的活动查询(长时间运行,30秒+)可以运行读取 从一个版本/快照,当正在应用WAL更新时,所以 当WAL事务发生时,后续查询将获得WAL更新 承诺。我还没有完全消化PostgreSQL中使用的MVCC模型 [https://devcenter.heroku.com/articles/postgresql-concurrency],所以这是 只是我的假设 - 即使一个表在一个表中被删除/截断 WAL更新,当前运行的查询应该仍然可以工作,因为它使用了 它查询的表的版本/快照?
摘要:无论如何(即使有第三方扩展名)我们都可以同步奴隶 从一个主人,并将来自主人的那些更新应用于 奴隶,同时让任何执行时间的查询继续 一直运行到备用/从机完成?如果Hot Standby不能这样做, 你会为这种情况推荐什么?我们的情景就是我们 不停地同时运行查询postgres(一些在 ms,有些在几秒钟内,有些在几分钟内,)几乎没有时间用于WAL 要应用更新。我们使用过Bucardo,但那并不好 在这种情况下的选择,因为我们需要超过200多个表 同步,包括除我们的主要以外的40多个其他数据库的视图 数据库中。
非常感谢任何帮助。
谢谢!
答案 0 :(得分:17)
感谢Guillaume的回答,但幸运的是,从PostgreSQL 9.1开始,PostgreSQL有hot_standby_feedback
选项(你在postgresql.conf中的备用服务器上设置它),它不会杀死长时间运行的查询并允许WAL备用服务器的更新。这个答案归功于PostgreSQL邮件列表中的三个人(Raja / Albe / Scott),他们在邮件线程中帮助了我。希望这对于在stackoverflow上搜索此答案的人有所帮助。电子邮件主题可以在这里找到:
http://www.postgresql.org/message-id/D274E3C1.1113E8%awilliams@dresourcesgroup.com
http://www.postgresql.org/docs/9.1/static/hot-standby.html
摘录:
如果发现待机查询取消的数量不可接受,则存在补救可能性。第一个选项是设置参数
hot_standby_feedback
,这会阻止VACUUM
删除最近死行,因此不会发生清除冲突。如果这样做,您应该注意这将延迟清除主数据库上的死行,这可能会导致不希望的表膨胀。但是,清理情况不会比备用查询直接在主服务器上运行更糟糕,并且您仍然可以获得将备份执行卸载到备用服务器上的好处。在这种情况下,max_standby_archive_delay
必须保持较大,因为延迟的WAL文件可能已包含与所需备用查询冲突的条目。
解决方案实施:
以下是您应在备用服务器上配置postgresql.conf
的内容:
max_standby_archive_delay = -1
max_standby_streaming_delay = -1
hot_standby_feedback = on
答案 1 :(得分:0)
PostgreSQL是一个非常好的数据库引擎,因为大多数查询都不会锁定表。在内部,它在表中每行有一种修订系统,这意味着它可以在您的其他读取事务期间继续编写WAL。
日志对延迟也非常有抵抗力,除非你有大量的流量,否则它总会在某个时候赶上。
请确保您不使用锁定命令,并且您会没事。