PostgreSQL的基于日志的数据库复制技术自8.2版本以来就已经有了,到了9.0更加的完善,standby库已经支持READ ONLY的模式提供用户使用。
1. 基于WAL文件恢复的数据库复制
2. 基于stream的数据库复制
在设计以上两中复制场景时,需要注意以下几点:
1. 尽量使用类似的硬件和相同操作系统.
数据库复制的目的无外乎standby或提供查询用,硬件和primary节点差的太离谱当然不恰当的,所以为了安全,建议使用同等配置的硬件。
2. 尽量使用相同的系统配置。
如相同的数据库目录,相同的用户环境变量配置等等。
3. 给系统起个比较容易辨认的名字。
为了防止误操作,还是起个容易辨认的名字吧。
4. 保持系统时钟同步。
primary和standby的时间确保同步,否则后患无穷。
5. 确保primary和standby的系统时区(如 UTC)一致。
6. 监控一定要做好,如磁盘的监控,复制延时的监控,这样才能确保你的复制系统是健康有效的。
7. 合理的配置hot_standby参数
max_standby_archive_delay
max_standby_streaming_delay
vacuum_defer_cleanup_age
trace_recovery_messages
另外,在设计HOT_STANDBY场景时,还需要注意以下几点:
一、查询冲突
1. 资源(如CPU,I/O)
资源冲突比较容易理解,如当standby节点正在从主节点恢复数据时,需要占用大量的CPU和IO资源,这时在standby节点发生查询的话就会有资源方面的冲突。
2. 锁(如AccessExclusiveLocks)
举个例子来说明一下问题,当在主节点使用一个DDL语句如在一个5千万的表中加一个列,并设置默认值,这是一个比较耗时间的操作。 alter table tbl_users add column last_name varchar(64) default 'digoal'; 这个操作需要获取tbl_users表的排他锁,所以在standby也会获得这个锁,如果在standby节点有用户使用了和这个排他锁冲突的锁的话,在达到参数配置的延时后,这个用户进程将被cancel掉。
通过修改参数max_standby_archive_delay 和 max_standby_streaming_delay 等于-1可以避免因为锁冲突导致的cancel。把这两个参数设为-1就是说暂停standby的recover 操作.不过还是小心使用,可能导致WAL越来越多甚至溢出。
3. 清除数据
如主节点发生VACUUM事件时,根据MVCC原理PostgreSQL可能会收回当前数据库中所有QUERY都不能看到的tuples,所以在清楚前,主节点的清除进程是需要知道当前系统中存在query的版本信息的,而在standby中正在发生的query,主节点是无法获得这部分信息的。因此主节点发生的VACUUM回收的tuples在STANDBY节点也许是那里的query可见的tuples。这就是清除数据冲突。(目前,第二象限公司2ndQuadrant开发的repmgr模块可以实现primary节点能够获取standby的query信息,具体信息可以到相关网站查询)
vacuum_defer_cleanup_age 这个参数可以用来配置standby节点上面的发生这种冲突时recover 的 apply延时。
4. 其他
如在主节点drop database,standby节点的相关SESSION将退出。
因此,建议在hot standby中如果要跑比较LONG的事务,需要配置好比较大的中央日志服务器,阻止RECOVER的发生再来跑。或者使用repmgr这种第三方软件来减少冲突的发生。
完全冻结一个standby的推荐方法:
在 recovery.conf配置中去除restore_command and primary_conninfo 的设置, 并且设置Standby_mode = on。
重启standby,将进入冻结状态。(不恢复任何数据)