在一个生产系统中,通常都需要用高可用方案来保证系统的不间断运行。PostgreSQL 本身不支持任何多主群集解决方案,例如MySQL或Oracle。尽管如此,仍有许多商业和社区产品提供此实现,以及其他产品,例如PostgreSQL的复制或负载平衡。
本章将详细介绍如何实现PostgreSQL数据库的高可用方案。
通常数据库的高可用方案都是让多个数据库服务器协同工作,比如,当一台服务器失效时,另一台服务器可以顶替上去工作,这样就可以不中断对外服务或只中断很短的时间;或者让几台数据库同时提供服务,用户可以访问任意一台数据库,当其中一台出现问题时,访问其他数据库即可。但与为静态页面提供服务的Web服务器不一样的是,数据库中记录了数据,要想在多台数据库中切换,需要进行数据同步,所以数据同步是数据库高可用方案的基础。
从解决数据同步问题的方式来看,高可用方案可以分为以下几种。
目前随着PostgreSQL自身复制功能的增强,越来越多的技术方案开始基于PostgreSQL自身的复制方案进行设计,改造PostgreSQL源码的开源软件技术方案已越来越不活跃了,如pgcluster软件已发布的最新版本1.3还是在PostgreSQL8.0之上改造的,pgcluster-II目前还没有开源出来。所以本书不再介绍“基于改造PostgreSQL源码的高可用方案”。
服务的可靠性设计
主备方式的高可用方案是通过主备之间的数据同步来实现的,数据同步有异步和同步两种方式。同步方式的优点是在故障切换过程中,数据完全不丢失,但缺点也很明显,主要问题有:
如果系统可以容忍故障切换时丢失少量的数据,可以使用数据异步同步的方式。该方案需要避免备库落后主库太多,防止故障切换时丢失太多的数据。
要保证服务中断的时间尽量地少,还需要灵敏的故障检测。但故障检测太灵敏时,误触发的概率也会增加,所以需要选择一个合适的故障检测时间。这个故障检测时间通常在秒级别以上。想要做到秒级别以下是比较困难的。
系统中最重要的资源就是数据,如何保证数据不丢失,是数据库系统中需要重点考虑的事情。导致数据丢失的原因有很多,如硬件故障或损坏、软件Bug、.人为失误等,所以通常要备份数据,除非这个数据库不重要,丢失了也没有关系。
SAN是“Storage Area Network”的缩写,即“存储区域网络”。与TCP/IP网络不同,“存储区域网络”是专为存储系统而设计的,它使用FC协议,而TCP/IP网络是通用功能的网络,支持各种各样功能的网络。SAN网络的架构与以太网网络类似,通常的架构图如图20-1所示。
在图20-1中,存储设备可以是多台,存储设备和需要使用存储的服务器之间通过光纤线和 SANswitch连接,SAN Switch与以太网中的交换机类似。服务器上也插有类似以太网网卡的HBA卡。
使用SAN共享存储的 PostgreSQL高可用方案的架构图 如图20-2所示。
从该架构图看,两台数据库服务器共享一块或多块从存储上划出的磁盘。磁盘上格式化了文件系统,PostgreSQL的数据文件就存在此文件系统上。在主/备库上都可以看到此共享磁盘,在主库上此磁盘上的文件系统是挂起来的,备库上此文件系统没有挂起。当主库发生故障时,由第三方的高可用软件把文件系统在备库上挂起,然后再在备库上启动数据库即完成了切换。
实际上进行高可用切换时,并不像上面所说的这么简单,当主库发生故障时,可能只是主库与外部的网络断开了,它与存储设备的连接还是好的,同时文件系统还挂着,如果此时把文件系统在另一台机器上挂起来,像Ext3、Ext4、xfs等文件是不能同时在两台机器上挂起来的,同时挂起时,两台机器都会对文件系统进行写操作,这就会导致文件系统的损坏。
为了避免这种情况,最常用的方法是主库没有收到心跳时就自动重启(相当于“自杀”),或者备库在挂文件系统之前通过其他办法,如向服务器的IPMI接口(IPMI是智能平台管理接口的简称,是一种开放标准的硬件管理接口)发送重启主机的命令,让主库重启可阻止主库对文件系统的写操作。
另一种方法是使用存储提供的“reserve_lock”功能,备机在挂起文件系统之前,通知存储,让存储不允许主库写此磁盘以避免文件系统的损坏。更多关于 PostgreSQL 系列的学习文章,请参阅:PostgreSQL 数据库,本系列持续更新中。
SAN存储比较昂贵,使用该方案的成本较高。还有一种类似共享存储的廉价方案,即使用DRBD仿真共享存储的方案。
DRBD是“Distributed Replicated Block Device”的缩写,DRBD是一个开源软件,它的大部分功能都是在Linux内核中实现的,目前大多数Linux发行版本中都已带有DRBD软件。DRBD是通过用软件实现的、无共享的、服务器之间块设备内容的复制软件。
DRBD有以下两种模式。
数据同步的方式有以下三种。
在PostgreSQL9.X之前的版本中,不支持流复制时只能通过拷贝归档在主备库之间实现同步。不过相对于流复制,手工复制归档文件同步可以做到更灵活,若需要备库落后主库一段时间来防止人工误删除等逻辑错误,可以写一个脚本,使其每过一段时间才把主库上的归档拷贝到备库上,让备库应用这些日志,这样就可以保证备库一定是落后主库一定时间的。在落后的这段时间内,如果主库被误删除了数据,还可以在备库上找回相应的数据。
当使用异步流复制的方案时,进行高可用切换会丢失部分数据。这个方案可以用于切换时容忍丢失少量数据的场景中。这个方案的架构图如图20-4所示。
当使用同步流复制时,如果主库与从库之间的网络中断或从库出现问题,主库也会被hang 住,而此时只有一个主库和一个从库,那么是无法做高可用方案的。PostgreSQL的解决方案是使用两个从库,只要有一个从库是正常的,主库就不会 hang 住。这个方案的架构如图20-5所示。
基于触发器的同步方案
前面讲解了基于共享存储和WAL日志同步的高可用方案,这两种方案都是对整个数据库实例进行同步的,而本节讲解的基于触发器的同步方案,则可以做到只同步一部分数据,它更为灵活,但也有以下几个缺点:
基本此方案做的同步软件较多,常见的开源软件有:
在众多Postgresql 高可用模式中,主要的参与者有两位,Patroni 与 repmgr 。
Repmgr 是一款开源的基于postgres复制基础上的高可用软件,他基于2ndQuadrant 公司开发而来,提供完整的基于从安装到部署,从设置到管理以及监控的一体化的postgresql 高可用方案,并且支持手动的POSTGRESQL 高可用切换和自动切换的方案,支持看门狗的模式。
Patroni 本身起源于一个 Governor 的分支,来自于一个 compose 项目,在 Zalando 中被改进的原来越好用。https://github.com/zalando/patroni,这是一个 python 编写的开源工具组件,通过他来进行 POSTGRESQL 的集群高可用性的支持,通过分布式存储的方式来完成一致性模型,目前一般配合 etcd 基于 raft 协议的分布式系统来使用。
参考文章:https://zhengxianghang.blog.csdn.net/article/ details/130983853 https://zhengxianghang.blog.csdn.net /article/details/130984122