在生产服务器上更新Postgres,无需停机

我有一台运行Postgres 9.4的生产服务器。 数据库大于10 GB。 是否有可能升级到Postgres 9.5没有宕机和没有数据丢失?

升级教程build议在执行sudo pg_upgradecluster 9.4 main停止Postgres,但这可能需要很长时间。 更新10 GB群集可能需要几个小时!

我也试过pg_dump mydb > db.sql 。 删除数据库并在PG 9.4( psql -d mydb -f db.sql )中再次插入转储需要大约50分钟。

但是在PG 9.5中插入转储只能在7个小时之后完成。 尤其是创build索引真的很慢…

 2016-07-18 00:13:55 CEST [60358-5] ERROR: canceling autovacuum task 2016-07-18 00:13:55 CEST [60358-6] CONTEXT: automatic analyze of table ... 2016-07-18 00:36:20 CEST [60366-1] ERROR: canceling autovacuum task 2016-07-18 00:36:20 CEST [60366-2] CONTEXT: automatic analyze of table ... 2016-07-18 04:21:40 CEST [60361-1] ERROR: canceling autovacuum task 2016-07-18 04:21:40 CEST [60361-2] CONTEXT: automatic analyze of table ... 2016-07-18 07:55:19 CEST [61316-1] ERROR: canceling autovacuum task 2016-07-18 07:55:19 CEST [61316-2] CONTEXT: automatic analyze of table ... 

所以pg_upgradeclusterpg_dump都不是可接受的解决scheme。 即使使用PG 4,您也至less需要50分钟的停机时间。 因此:数据库如何在生产服务器或大型主 – 从集群上进行升级,而无需停机和数据丢失?

如果没有一些集群魔法,没有停机时间是不可能的。

其他一些可能性:

  1. 使用pg_upgrade--link选项。 使用此选项,原始数据库文件不会被复制,而是被硬连接到新的目录,极大地加速了这个过程。 请注意,这将永久性改变源数据库文件。
  2. 使用pg_dump并在新的数据库上恢复。 通过禁用新数据库中的同步写入,可以大大缩短所需的时间(在新的PG实例的configuration文件中, fsync = false
  3. 侧安装一个新的PG实例,让它运行在不同的端口上。 然后,使用pg_dump通过networking将转储加载到新实例。 完成后,交换端口并使用新的实例。

我想你已经解决了,所以也许对于其他类似的问题。

经过几年的工作,从8.4版本到最新的Postgresql 9.6,我会build议这些情况 – 不要“升级”。 如果可以使用最新版本的OS创build新机器或新的云实例(非常重要 – 防止许多问题)以及最新的pg版本和重复数据。

如何复制数据取决于您的应用程序,PostgreSQL版本和周边环境。 数据库〜10 GB不是那么大,所以对你有好处。 我使用大于400 GB的数据库,所以想象这里存在多重问题。

  • Pg_dump 9.4已经允许你使用多个CPU核心转储到具有多个作业的目录格式,这可以非常显着地降低转储时间 – 除非你在一个大表中包含所有内容:-)
  • 或者对于第9和第9页,您可以使用pglogical扩展名,这是一个非常棒的解决scheme,但请注意 – 要在master上运行pglogical,您必须重新启动postgres,因为扩展名必须添加到postgresql.conf文件中shared_preload_libraries ='pglogical'看到这里: http : //postgresql.freeideas.cz/pglogical-postgresql-9-6-small-hints-debian/所以我强烈build议在一些其他的实例之前testing它与相同的版本! 如果连接string没有被硬编码到应用程序:-),那么切换到新实例安排一些简短的维护时间窗口将客户端切换到新的数据库 – 但是在这种情况下,您可以在旧计算机上准备好连接configuration到新机器的pgbouncer,停止旧的数据库,切换pg端口(假设5432)pgbouncer和处理后续连接string,如果可能的话…
  • 或者,也许你的应用程序没有这么多的新数据,你可以在你的应用程序中使用最新的备份和叉插入/更新到这两台机器? 切换客户端,当你确定一切正常?

我在现实生活中看到了所有这些场景的变体。 所以玩得开心! 我交叉手指:-)

升级(几乎)没有停机时间应该是可能的pglogical 。 至less对于PostgreSQL> = 9.4和更新它应该工作。

这是一个比较新的项目(2016),它基于PostgreSQL的双向复制代码。 对于安装,您需要使用2ndQuadrant存储库 。

README中描述了使用情况,需要重新启动数据库(您必须更新复制configuration),但至less不应导致数小时的停机时间。

与repmgr不同的是 , pglogical是用于一次数据库复制的,这比复制二进制WAL文件要花费更多的时间。

首先为每个需要复制(升级)的数据库启用扩展:

 CREATE EXTENSION pglogical; 

目前所有的命令都需要以超级用户身份执行( postgres )。 从创build“主节点”( provider )开始:

 SELECT pglogical.create_node( node_name := 'provider1', dsn := 'host=providerhost port=5432 dbname=db' ); 

并标记用于复制的模式:

 SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']); 

和序列复制:

 SELECT pglogical.replication_set_add_all_sequences('default', ARRAY['public']); 

请注意,每个表都需要一个主键,否则复制将不会启动。 不像其他备份方法在这里表一致性问题。

继续“备用节点”( subscriber

 SELECT pglogical.create_node( node_name := 'subscriber1', dsn := 'host=thishost port=5432 dbname=db' ); 

最后开始复制:

 SELECT pglogical.create_subscription( subscription_name := 'subscription1', provider_dsn := 'host=providerhost port=5432 dbname=db' );