前言
简单记录一下postgresql主从的实现方式之一——基于Standby的异步流复制,这是PostgreSQL9.x版本(2010.9)之后提供的一个很nice的功能,类似的功能在Oracle中是11g之后才提供的active dataguard和SQL Server 2012版本之后才提供的日志传送,此处再次为pg鼓掌,确实是一个很棒的开源数据库。废话不多说,本篇blog就详细记录一下在pg9.5中实现Hot Standby异步流复制的完整配置过程和注意事项。
Standby数据库原理
简单介绍一些基础概念与原理,首先我们做主从同步的目的就是实现db服务的高可用性,通常是一台主数据库提供读写,然后把数据同步到另一台从库,然后从库不断apply从主库接收到的数据,从库不提供写服务,只提供读服务。在postgresql中提供读写全功能的服务器称为primary database或master database,在接收主库同步数据的同时又能提供读服务的从库服务器称为hot standby server。
PostgreSQL在数据目录下的pg_xlog子目录中维护了一个WAL日志文件,该文件用于记录数据库文件的每次改变,这种日志文件机制提供了一种数据库热备份的方案,即:在把数据库使用文件系统的方式备份出来的同时也把相应的WAL日志进行备份,即使备份出来的数据块不一致,也可以重放WAL日志把备份的内容推到一致状态。这也就是基于时间点的备份(Point-in-Time Recovery),简称PITR。而把WAL日志传送到另一台服务器有两种方式,分别是:
- WAL日志归档(base-file)
- 流复制(streaming replication)
第一种是写完一个WAL日志后,才把WAL日志文件拷贝到standby数据库中,简言之就是通过cp命令实现远程备份,这样通常备库会落后主库一个WAL日志文件。而第二种流复制是postgresql9.x之后才提供的新的传递WAL日志的方法,它的好处是只要master库一产生日志,就会马上传递到standby库,同第一种相比有更低的同步延迟,所以我们肯定也会选择流复制的方式。
在实际操作之前还有一点需要说明就是standby的搭建中最关键的一步——在standby中生成master的基础备份。postgresql9.1之后提供了一个很方便的工具—— pg_basebackup,关于它的详细介绍和参数说明可以在官网中查看(pg_basebackup tool),下面在搭建过程中再做相关具体说明,关于一些基础概念和原理先介绍到这里。
详细配置
下面开始实战,首先准备两台服务器,我这里开了2个虚机做测试,分别是:
- 主库(master) centos-release-7-2.1511 192.168.111.101 postgresql 9.5.5
- 从库(standby) centos-release-7-2.1511 192.168.111.102 postgresql 9.5.5
从主库配置开始。
主库配置
注意此处的操作都是在主库(192.168.111.101)上进行的,首先打开数据目录下的postgresql.conf文件然后做以下修改:
- listen_address = ‘*’(默认localhost)
- wal_level = hot_standby(默认是minimal)
- max_wal_senders=2(默认是0)
- wal_keep_segments=64(默认是0)
下面稍作说明,第一个不用说了,wal_level表示启动搭建Hot Standby,max_wal_senders则需要设置为一个大于0的数,它表示主库最多可以有多少个并发的standby数据库,而最后一个wal_keep_segments也应当设置为一个尽量大的值,以防止主库生成WAL日志太快,日志还没有来得及传送到standby就被覆盖,但是需要考虑磁盘空间允许,一个WAL日志文件的大小是16M:
如上图,一个WAL日志文件是16M,如果wal_keep_segments设置为64,也就是说将为standby库保留64个WAL日志文件,那么就会占用16*64=1GB的磁盘空间,所以需要综合考虑,在磁盘空间允许的情况下设置大一些,就会减少standby重新搭建的风险。接下来还需要在主库创建一个超级用户来专门负责让standby连接去拖WAL日志:
create user repl superuser password ‘111111‘;
接下来打开数据目录下的pg_hba.conf文件然后做以下修改:
如上图,这行配置的意思是允许用户repl从192.168.111.0/24网络上发起到本数据库的流复制连接,简言之即允许从库服务器连接主库去拖WAL日志数据。主库配置很简单,到此就算结束了,启动主库并继续配置从库。
从库配置
从此处开始配置从库(192.168.111.102),首先要通过pg_basebackup命令行工具在从库上生成基础备份,命令如下:
./pg_basebackup -h 192.168.111.101 -U repl -F p -x -P -R -D /usr/local/postgresql/data/ -l replbackup20161122
下面简单做一下参数说明(可以通过pg_basebackup --help
进行查看),-h
指定连接的数据库的主机名或IP地址,这里就是主库的ip。-U
指定连接的用户名,此处是我们刚才创建的专门负责流复制的repl用户。-F
指定了输出的格式,支持p(原样输出)或者t(tar格式输出)。-x
表示备份开始后,启动另一个流复制连接从主库接收WAL日志。-P
表示允许在备份过程中实时的打印备份的进度。-R
表示会在备份结束后自动生成recovery.conf文件,这样也就避免了手动创建。-D
指定把备份写到哪个目录,这里尤其要注意一点就是做基础备份之前从库的数据目录(/usr/local/postgresql/data)目录需要手动清空。-l
表示指定一个备份的标识,运行命令后看到如下进度提示就说明生成基础备份成功:
如上图,由于我们在pg_hba.conf中指定的md5认证方式,所以需要输入密码。最后还需要修改一下从库数据目录下的postgresql.conf文件,将hot_standby
改为启用状态,即hot_standby=on
。到此为止就算配置结束了,我们现在可以启动从库,如果启动成功就说明配置成功,在从库运行pg_ctl start -l /usr/local/postgresql/log/pg_server.log
启动后看一下日志:
如上图,确实报了一个严重错误,根据提示说明的是data目录的权限有问题,该目录的权限应当设置为rwx(0700),那么我们切回root用户重新给data目录设置权限:
chmod -R 0700 /usr/local/postgresql/data/
之后再次切回postgres用户启动从库,这次发现并没有任何错误日志了,通过ps -ef|grep postgres
查看一下进程:
如上图,可以看到流复制的进程,同样的主库也能看到该进程,现在就可以建表做测试了,在master服务器(192.168.111.101)中的postgres库下建一张表并添加几条数据:
然后在standby服务器(192.168.111.102)中进行查看同步情况:
如上图,可以看到完美同步,那么从库是否能删除呢?测试一下:
如上图,standby的数据无法删除,正如我们之前说的,standby只提供只读服务,而只有master才能进行读写操作,所以master才有权限删除数据,master删除的同时standby中的数据也将同步删除,关于异步流复制的内容到这里就已经全部介绍完毕了。
总结
简单记录一下PostgreSQL9.5.5通过流复制实现主从同步的过程,希望对遇到同样问题的朋友有所帮助,The End。