作者:MeshCloud脉时云公有云架构师周宽 本文介绍了如何将本地PostgreSQL集群迁移到GoogleCloud。此方法使用PgBouncer作为连接池程序,这可以最大限度地减少应用停机时间,并有助于设置用于监控结果的工具。本文的目标受众是在Linux环境中工作的PostgreSQL管理员和系统管理员。 在下图中,PgBouncer实例位于本地主实例的前面。 有了连接池,客户端便会在故障切换到GoogleCloud时路由到替代节点,而无需重新部署应用配置或进行应用级更改。 下图演示了迁移过程。 如需执行迁移,请关停当前主实例,然后将从属GoogleCloud副本提升为主实例。PgBouncer会将流量重新路由到GoogleCloud上的新主节点。一、目标在GoogleCloud中设置PostgreSQL。在ComputeEngine上设置复制功能。将数据播种(seed)至新实例。在GoogleCloud上设置PostgreSQL集群。切换到新服务器。实现监控功能。二、准备工作登录您的GoogleCloud帐号。选择或创建一个GoogleCloud项目。确保项目已启用结算功能。启用ComputeEngineAPI。GoogleCloud控制台启动CloudShell。 本教程使用gcloud和gsutil命令,您可以在通过GoogleCloud控制台启动的CloudShell实例中运行这些命令。如果要在本地工作站上使用gcloud和gsutil,请安装GoogleCloudCLI。三、设置环境 首先执行以下任务:在GoogleCloud中设置PostgreSQL。在ComputeEngine上设置复制功能。 然后,在开始复制主实例之前,将数据播种到新实例。3。1在GoogleCloud中设置PostgreSQL 请按照如何设置PostgreSQL以通过热备用模式实现高可用性和复制功能中所述的步骤操作,只需几分钟即可在GoogleCloud上设置好PostgreSQL。您可在ComputeEngine上的Ubuntu虚拟机实例中配置PostgreSQL。3。2在ComputeEngine上设置复制功能 请按照如何在GoogleComputeEngine上设置PostgreSQL中所述的步骤配置PostgreSQL,使其在ComputeEngine上以热备用模式运行。您需要使用两个ComputeEngine实例。一个实例用于运行主PostgreSQL服务器,另一个实例用于运行备用服务器。 尽管用于配置PostgreSQL的属性在主实例和从属实例之间有所不同,但属性文件应当相同,以便实现无缝故障切换。 PostgreSQL集群中的从属实例通过recovery。conf文件的存在来表示。 在大多数情况下,都有必要分离数据库的数据目录与启动磁盘。在本例中,数据库文件存储在database处装载的目录中。 如需修改主实例上的postgresql。conf文件以设置复制功能,请使用以下命令:wallevelhotstandbyarchivemodeonarchivecommandtest!fpostgresqlarchivedirfcpppostgresqlarchivedirfmaxwalsenders3listenaddresseswalkeepsegments8 如需修改副本上的postgresql。conf文件,请使用以下命令:hotstandbyonstandbymodeonprimaryconninfohost{PRIMARYIP}port5432userrepuser 向副本发送Read请求可以减轻主实例的负载。3。3播种数据 由于主数据库有事务日志限额,因此大多数PostgreSQL迁移都需要将数据种子设定为新实例,然后才能开始复制主实例。可通过以下某种方式播种数据:使用Pgdump将单个数据库转储为一个脚本或归档文件。使用Pgbasebackup获取正在运行的数据库集群的二进制副本。使用rsync将数据文件夹复制到副本。将旧备份恢复到副本。 在上述方式中,推荐的方式是将旧备份恢复到副本。采用这种解决方案时,系统性能不会因传输数据量大而受到影响,并且当前集群仍能够继续正常运行。 在数据库的初始种子设定完成之后,您可以使用rsync命令将更改馈送到执行备份后生成的副本;该命令会同步两个实例之间的数据目录。如果备份比主实例滞后太多,无法通过正常复制与之同步,那么这步操作非常重要。四、在GoogleCloud上设置PostgreSQL集群 您可以使用级联复制功能创建PostgreSQL集群。首先迁移数据库,如下图所示。 4。1迁移数据库从正在运行的主服务器获取完整备份(label可以是任何标签):echoselectpgstartbackup(label,true);sudosupostgrescpsqlsudotarcvfzpostgresqlAAAAMMDD。tar。gzPGDATA PGDATA是PostgreSQL的主数据目录。在GoogleCloud项目中创建一个名为gs:pgrepo的存储分区。将备份转移到刚刚创建的存储分区:mastergsutilcppostgresqlAAAAMMDD。tar。gzgs:pgrepo将备份文件转移到GoogleCloud主实例:newmastergsutilcpgs:pgrepopostgresqlAAAAMMDD。tar。gz将备份文件恢复到GoogleCloud主实例:newmaster(cd;tarxvfpostgresqlAAAAMMDD。tar。gz)在PGDATA目录中创建一个包含以下内容的recovery。conf文件:standbymodeonprimaryconninfoport5432host{runningmasterip}user{replicationuser}applicationnamecloudmastertriggerfiletmpfailover。postgresql。5432 注意:triggerfile值可以采用任何名称,并且可以放在您指定的任何目录中。为便于记忆,此示例使用名称failover。postgresql。5432,该文件旨在对端口5432上运行的PostgreSQL强制进行故障切换。启动PostgreSQL服务:sudoservicepostgresqlstart等待GoogleCloud主服务器与正在运行的主实例同步。在日志中,您可以看到如下所示的内容:tailfvarlogpostgresqlpostgresqllog。。。2018092217:59:54UTCLOG:consistentrecoverystatereachedat0230000F02018092217:59:54UTCLOG:databasesystemisreadytoacceptreadonlyconnections。。。 注意:0230000F0是pgxlogID。您的ID会有所不同。 此外,您可以搜索masterpgstatreplication来确定新的从属实例(称为cloudmaster)是否已连接:postgresxExpandeddisplayison。postgresselectfrompgstatreplicationwhereapplicationnamecloudmaster;〔RECORD1〕pid16940usesysid16402usenamerepmgrapplicationnamecloudmaster。。。4。2创建从属数据库关停数据库和服务器:sudoservicepostgresqlstopsudoshutdownhnow如需验证服务已经停止,请运行以下命令:gcloudcomputeinstancesdescribemasterinstancenamegrepstatus 在输出中,实例的状态将显示为TERMINATED:status:TERMINATED 接下来,创建数据磁盘的快照以帮助创建新的从属实例。在GoogleCloudConsole中,转到快照页面。基于PostgreSQL磁盘新建一个快照。启动GoogleCloud主服务器。转到虚拟机实例页面,点击masterinstancename,然后点击启动。 PostgreSQL服务即会自动启动。如需检查这一点,请运行以下命令:psaxgreppostgres 结果应该类似如下所示:1398?S0:00usrlibpostgresql9。3binpostgresDvarlibpostgresql9。3maincconfigfileetcpostgresql9。3mainpostgresql。conf1454?Ss0:00postgres:checkpointerprocess1455?Ss0:00postgres:writerprocess1456?Ss0:00postgres:walwriterprocess1457?Ss0:00postgres:statscollectorprocess在GoogleCloud控制台中,转到虚拟机实例页面,然后点击创建实例。对于启动磁盘,选择Ubuntu14。04。点击管理、磁盘、网络、SSH密钥,然后根据您之前创建的快照添加新的磁盘。启动新服务器并装载该磁盘:sudomkdirdatabasesudomountdevsdb1database安装PostgreSQL:sudoaptgetinstallpostgresqlsudoservicepostgresqlstop配置数据目录和复制值。从GoogleCloud主实例中复制postgresql。conf文件和pghba。conf文件,然后修改recovery。conf文件以包含以下内容:standbymodeonprimaryconninfoport5432host{cloudmasterip}user{replicationuser}applicationnamecloudslave{identifier}recoverytargettimelinelatest使用新的配置文件启动PostgreSQL服务,使其指向GoogleCloud主实例:sudoservicepostgresqlrestart验证服务正在运行:psaxgreppostgres使用以下查询检查GoogleCloud主服务器:postgresxExpandeddisplayison。postgresselectfrompgstatreplicationwhereapplicationnamelikecloudslave;〔RECORD1〕pid2466usesysid16402usenamerepmgrapplicationnamecloudslave1。。。重复上述步骤来创建更多从属实例。五、切换到新服务器将PgBouncer中的配置文件更改为指向新的GoogleCloud主服务器。在PgBouncer实例中,关停PgBouncer,使用failover。postgresql。5432触发器文件提升新的主实例,然后重启PgBouncer:servicepgbouncerstop;ssh{cloudmasterip}touchtmpfailover。postgresql。5432;servicepgbouncerstart六、查询示例 检查服务器上的所有并发连接数:selectfrompgstatactivity; (主实例)检查复制状态:selectfrompgstatreplication; (主实例)检查副本应用数据的延迟情况:selectpgxloglocationdiff(writelocation,replaylocation)frompgstatreplication; (主实例)检查复制的字节延迟情况:selectclienthostname,clientaddr,pgxloglocationdiff(pgstatreplication。sentlocation,pgstatreplication。replaylocation)ASbytelagfrompgstatreplication; (从属实例)检查数据库是否为副本:selectpgisinrecovery(); (从属实例)检查上次从主实例接收的数据:selectpglastxlogreceivelocation(); (从属实例)检查上次从主实例应用的数据:selectpglastxlogreplaylocation(); (从属实例)检查复制延迟时间(以秒为单位):selectnow()pglastxactreplaytimestamp();