欢迎您光临本站,如有问题请及时联系我们。

秒级实现PostgreSQL版本升级方案

  一、为什么要升级PostgreSQL数据库

  看到这个题目,很多使用PostgreSQL的同学可能会这样问,我当前使用的PostgreSQLDBInstance的MajorVersion虽然低一些,但是它一直很稳定,并且暂时也能满足当前业务对性能的需求,那我为什么还要去花费时间,消耗经历去做数据库升级呢?


  1、对PostgreSQL熟悉的人或者经常看官方文档的同学会发现,基本上每年PostgreSQL都会有一个大版本发布,而随之发布的还有一些新特性,比如说


  9.3版本的新增物化视图、支持事件触发


  9.4版本新增的jsonb字段类型、可以通过sql命令altersystem来直接修改数据库参数命令以及新增的logicaldecoding特性


  9.5版本新增的支持upsert特性、新增的BRIN索引


  9.6版本新增的对顺序扫描的并行执行、为了提高数据库的可靠性,允许多台standby数据库同时处于sync状态


  10.0版本新增的支持表级的逻辑复制,允许对其进行发布和订阅、定义表分区及提高并行查询的效率


  这里简单的列一下每个版本的新特性,如果想了解个多的新特性或者每个特性的详细信息,请参考https://www.postgresql.org/docs/current/static/release.html


  每一个新特性在其特定的使用场景下,都会对数据库和应用程序的性能有质的飞跃,都会极大的节省开发及运维人员的时间成本、人力成本,所以我们为什么不站在巨人的肩膀上前行呢?


  2、PostgreSQL社区成员每年只会同时维护5个主板本的PostgreSQL数据库,也就是说每个数据库版本都是有生命周期的,从今年九月份(2017-09)开始,对于9.3以前的版本数据库不再进行维护,当然你依然可以在官网上下载9.3以前的版本使用,但是如果在使用过程中出现了小bug,那么社区成员只会在维护的版本中修复,9.3以前的版本不会进行任何修改,所以为了避免低版本的bug引发应用程序故障崩溃,升级数据库还是很有必要的。


  数据库


  二、传统升级方案剖析

  数据库升级分为两种,一种是小版本迭代升级,另一种是主板本升级。小版本升级很简单,只需要重启一下数据库即可,我们这里主要说一下主板本升级。做过数据库升级方案的同学或者熟读官方文档的同学可能知道,官方提供两种大版本升级方案,分别是pg_upgrade和pg_dumpall,这里对这两种方式的优缺点做一下整理:


  数据库


  在我们生产环境中,尤其是核心的生产环境中,数据库都是以集群的方式存在的,因为数据是一个公司的核心命脉,所以如果要以传统的方式来升级数据库,绝大部分同学会选择使用pg_dumpall的方式来实现,但是因为pg_dumpall的升级时间是与整个数据库集群的数据量成正比的,所以升级过程中需要长时间停止程序的写服务,这对核心的业务程序(特别是有99.999保证的程序)来说是不可接受的,那么既要升级数据库主板本,又要保证核心程序的99.999,就需要借助其他方式,而PGQ就可以实现秒级升级数据库。


  三、PGO原理及特征

  首先我们先来了解一下什么是pgq,其实pgq是skytools的一个模块,而skytools是skype公司的一个复制和容错的工具包。skytools里面有三个模块,分别是pgq、londiste和walmgr。


  pgq是一个用PL/pgSQL、Python和C编写的一个队列系统,它分为3个部分,分别是producers、ticker和consumers,其中producers负责调用数据库的存储程序将数据转换成event,ticker则负责将event进行批次划分,而consumers则负责将event转换成sql语句;londiste是一个用Python写的复制工具,它利用pgq做为事件传输;walmgr则是一个脚本,主要用来对wal做归档,对数据库做初始化备份以及恢复。


  在pgq整个集群中还有node的概念,分别是rootnode、branchnode、leafnode。Root节点是整个集群的数据唯一入口,同时负责向下游推送event,root节点的下游可以为branch节点、leaf节点以及通过调用pgq的api接口自定义程序将数据同步到其他平台,比如greenplum、elasticsearch、kafka、sqlserver等等;branch节点是转换节点,负责接受上游推送下来的数据写入到自己对应的db中,同时将event推送到下游(如果有下游的情况下),branch可以挂载在root节点下,也可以挂载在其他branch节点;leaf节点负责接受上游推送的event写入到自己对应的数据库中,它的挂载方式与branch节点一样。


  个人一直将pgq做为一个增量数据同步工具来使用,现在对pgq的特点进行一下总结:


  1、数据从一个节点到下游节点可以在毫秒级完成,数据同步的快慢由自定义时间和自定义批次量的大小来根据业务需求灵活控制;


  2、pgq对root节点和branch节点的下游挂载节点个数没有限制,如果一个branch节点出现故障,那么可以将此节点的下游节点通过change-provider命令挂载到其他节点,在切换的过程中由ticker值来控制保证数据不会丢失,而故障节点会一直重试,直到故障恢复或在集群中摘除次节点;


  3、root节点可以根据业务需要通过takeover命令来和branch节点进行切换,同样可以保证数据不会丢失;


  4、pgq的同步对象是tables和sequences,可以一次添加多张表进行同步,pgq会对表先做copy全量同步,然后在进行增量同步,同步过程中不会影响其他表;


  5、pgq需要同步表必须还有主键或者非空的唯一索引,不满足此条件的表无法加入到同步集群中;


  6、pgq是一个开源工具,可以调用其api接口将数据同步到其他平台,如greenplum、elasticsearch、kafka、sqlserver……


  7、pgq是单进程程序,所以不适合一次性操作上百万上千万的数据,建议分批次多次执行;


  8、官方发布的release版本目前只支持到pg9.5,需要修改源码中keywrods的路径才可以支持pg9.6以及pg10版本;


  原PGQ同步集群架构


  架构


  branch节点切换后的同步集群架构


  四、PostgreSQL主板本升级过程

  1、先要确定pgq的版本与PostgreSQL的版本是否匹配,如果不匹配需要手工修改一下pgq的源码


  visql/pgq/triggers/stringutil.c


  –*src/include/parser/keywords.h


  +*src/include/common/keywords.h


  2、安装pgq同步集群,需在低版本数据库配置root节点环境,高版本数据库配置branch节点环境


  两个节点都需要配置pgqd.ini文件,同时root节点配合pgq_root95.ini文件,branch节点配置pgq_branch96.ini文件,配置文件的名字自己定义即可


  vi.pgqd.ini


  [pgqd]

  logfile=pgqd.log

  pidfile=pgqd.pid

  base_connstr=host=l-pgtest1.devuser=pgqpassword=pgqport=5432

  database_list=postgres

  ticker_period=1


  —————————


  vipgq_root.ini


  [londiste3]

  job_name=pgq_root

  db=host=l-pgtest1.devport=5432dbname=postgresuser=pgqpassword=pgq

  pgq_queue_name=pgq

  logfile=pgq_root.log

  pidfile=pgq_root.pid

  —————————-

  vipgq_branch.ini


  [londiste3]

  job_name=pgq_branch96

  db=host=l-pgtest1.devport=8432dbname=postgresuser=pgqpassword=pgq

  pgq_queue_name=pgq

  logfile=pgq_branch96.log

  pidfile=pgq_branch96.pid


  pgq_queue_name在整个pgq集群中要保持一致,而job_name在整个集群中要唯一,同时这个集群中所有的数据库都要创建一个具有superuser权限的用户,比如此例中的pgq


  创建root节点:londiste3pgq_root.inicreate-rootpgq_root‘host=l-pgtest1.devport=5432dbname=postgresuser=pgqpassword=pgq’


  创建branch节点:londiste3pgq_branch.inicreate-branchpgq_branch96‘host=l-pgtest1.devport=8432dbname=postgresuser=pgqpassword=pgq’–provider=’host=l-pgtest1.devport=5432dbname=postgresuser=pgqpassword=pgq’


  3、添加同步对象(表)


  先要对数据库的结构进行同步,因为pgq只关心数据,所以各个节点的数据结构要保持一致,然后确定要添加的同步表具有主键或者唯一索引,否则添加同步表报错


  londiste3pgq_root.iniadd-tabletablename1tablename2—以此命令为模板来添加同步表


  4、所有的同步表都添加完后,确定一下同步集群是否正常,可以通过各个节点的日志来看,也可以同步命令来看


  londiste3pgq_root.inistatus


  5、通过切换root节点的方式来实现数据库升级,在branch节点上执行takeover命令来实现


  londiste3pgq_branch.initakeoverpgq_root–其中pgq_branch.ini是branch节点的配置文件,pgq_root是root节点名


  6、如果是在本服务器上进行操作,还需要重启一下高版本数据库实例,因为要改一下dbinstance的端口号;如果是升级到其他服务器则不用进行此操作


  五、PostgreSQL主板本升级总结

  1、数据库升级秒级实现,应用停服时间短;


  2、升级回滚方式灵活,同样是以切换pgqroot节点的方式来实现;


  3、可以保证升级前后PostgreSQL的兼容性,尤其是一些Extension的兼容性;


来源:本文由E8运维原创撰写,欢迎分享本文,转载请保留出处和链接!