免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9984 | 回复: 4

PostgreSQL9.0 standby数据库介绍及搭建方法 [复制链接]

论坛徽章:
3
数据库技术版块每日发帖之星
日期:2015-06-18 22:20:00数据库技术版块每日发帖之星
日期:2015-06-21 22:20:00数据库技术版块每日发帖之星
日期:2015-08-27 06:20:00
发表于 2010-08-21 23:20 |显示全部楼层
本帖最后由 osdba 于 2010-08-22 12:41 编辑

PostgreSQL数据库提供了类似Oracle的standby数据库的功能。PostgreSQL9.0 standby数据库在应用WAL日志的同时,也可以提供只读服务,这是PostgreSQL9.0中最激动人心的功能,这个功能在oracle数据库中也只是最新版本11g中才有的新功能。这个功能在oracle中叫active dataguard,在PostgreSQL中称为hot standby。在利用日志恢复数据的同时可以用只读的方式打开数据库,用户可以在备用数据库上进行查询、报表等操作,也可用做读写分离。在PostgreSQL9.0之前,也可以搭建standby数据库,但standby数据库只能处于恢复状态中,不能打开,也不支持只读打开。而这种情况在9.0之后彻底改变了。
    PostgreSQL 9.0中日志传送的方法有两种:
  • 基于文件(base-file)的传送方式,这种方式是PostgreSQL9.0之前就提供的方法。也就是服务器写完一个WAL日志文件后,才把WAL日志文件拷贝到standby数据库上去应用。
  • 流复制(streaming replication)的方法,这是PostgreSQL9.0才提供的新方法。这个方法就是事务提交后,就异步的把生成的日志传送到standby数据库上应用,这比基本文件的日志传送方法有更低的数据延迟。

    基于文件(base-file)的传送方式在PostgreSQL8.X中就有的方式,这里不就介绍了,这里主要介绍流复制的standby的搭建方法,设置步骤如下:
    1. 对主数据库做一个基础备份,然后把基础备份拷贝到standby机器,把基础备份恢复到standby机器上
    2. 在主库上设置wal_level = hot_standby。
    3. 在主数据库上设置wal_keep_segments为一个足够大的值,以防止主库生成WAL日志太快,日志还没有来得及传送到standby,就会循环覆盖了;
    4. 在主数据库上设置max_wal_sender参数,这个参数是控制主库可以最多有多少个并发的standby数据库;
    5. 在主数据库上建一个超级用户,standby数据库会使用这个用户连接到主库上拖WAL日志。
    6. 在主数据库上的pg_hba.conf中设置listen_addresses和连接验证选项,允许standby数据库连接到主库上来拖WAL日志数据,如下所示:
# TYPE DATABASE USER CIDR-ADDRESS METHOD
host replication repl 192.168.1.100/32 md5    其中数据库名必须填“replication”, 这是一个为standby连接使用了一个虚拟的数据库名称。用户repl就是步骤4上给standby连接使用的在主库上建的一个超级用户。192.168.1.100就是standby数据库的IP地址。
   
    7.   在备份数据库上建一个recovery.conf,设置以下几项:
standby_mode = 'on'
primary_conninfo = 'host=127.0.0.1 port=5432 user=repl password=replpwd'
trigger_file = '/opt/pgstb/trigger_activestandby'

   standby_mode设置为'on',表明数据库恢复完成后,不会被找开,仍然处理等待日志的模式。
   primary_conninfo上standby连接到主数据库所需要的连接串。
   
    8. 启动standby数据库,这样standby数据库就算搭建好了。

    下面以实际的例子,为看standby上如何搭建的,我把standby数据库与主数据库建在一台机器上。
主数据库的数据目录为:/opt/pgpri,standby数据库的数据目录为/opt/pgstb。
    为了便于启动和停止PostgreSQL,在.bash_profile文件中添加以下两行:
alias pgstart='pg_ctl -D $PGDATA start'
alias pgstop='pg_ctl kill INT `head -1 $PGDATA/postmaster.pid`'
   
    在主数据库的/opt/pgpri/postgresql.conf文件中设置如下配置项:
wal_level = hot_standby
max_wal_senders = 2
wal_keep_segments = 32

    在主数据库中的/opt/pgpri/pg_hba.conf中添加如下配置:
host replication repl 127.0.0.1/32 md5

    在数据库中建一个repl用户用于给standby连接主库使用:
#psql -d postgres
postgres=# create user repl superuser password 'replpwd';
CREATE ROLE

    重新启动主数据库,让配置生效:
osdba@osdba-laptop:/opt/pgpri$ pgstop
LOG: received fast shutdown request
LOG: aborting any active transactions
LOG: autovacuum launcher shutting down
osdba@osdba-laptop:/opt/pgpri$ LOG: shutting down
LOG: database system is shut down
osdba@osdba-laptop:/opt/pgpri$ pgstart
server starting
osdba@osdba-laptop:/opt/pgpri$ LOG: database system was shut down at 2010-08-21 22:33:29 CST
LOG: database system is ready to accept connections
LOG: autovacuum launcher started

    对主数据库做一个基础备份:
先用select pg_start_backup();命令把数据库切换到备份状态:
osdba@osdba-laptop:/opt/pgpri$ psql -d postgres
psql (9.0beta4)
Type "help" for help.

postgres=# SELECT pg_start_backup('/opt/pgstb');
pg_start_backup
-----------------
0/1000020
(1 row)

postgres=#

    由于我的standby数据库与主库在一台机器上,这时只需要把主数据库目录拷贝到备库目录就可以了:
osdba@osdba-laptop:/opt$ cp -r pgpri/* pgstb/.
osdba@osdba-laptop:/opt$ cd pgstb/.
osdba@osdba-laptop:/opt/pgstb$ ls
backup_label global pg_hba.conf pg_multixact pg_stat_tmp pg_tblspc PG_VERSION postgresql.conf postmaster.pid
base pg_clog pg_ident.conf pg_notify pg_subtrans pg_twophase pg_xlog postmaster.opts

    拷贝完成后,结束主库的备份状态:
postgres=# SELECT pg_stop_backup();
NOTICE: WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup
pg_stop_backup
----------------
0/1000288
(1 row)

    修改备库的配置文件/opt/pgstb/postgresql.conf文件中的相关项为如下内容:
port = 5433
hot_standby = on
    由于备库与主库在同一台机器上,给备份指定一个不同的监听端口,这里修改为5433,主库是默认的5432端口,把其中的hot_standby设置为on。

    拷贝示例文件/usr/local/pgsql/share/recovery.conf.sample到/opt/pgstb目录下,然后改名成recovery.conf,修改相关的配置项为如下内容:
standby_mode = 'on'
primary_conninfo = 'host=127.0.0.1 port=5432 user=repl password=replpwd'
trigger_file = '/opt/pgstb/trigger_activestb'

    删除原先从主库上过来的/opt/pgstb/postmaster.pid文件,然后启动备库:
osdba@osdba-laptop:/opt/pgstb$ rm postmaster.pid
osdba@osdba-laptop:/opt/pgstb$ export PGDATA=/opt/pgstb
osdba@osdba-laptop:/opt/pgstb$ echo $PGDATA
/opt/pgstb
osdba@osdba-laptop:/opt/pgstb$ pgstart
server starting
osdba@osdba-laptop:/opt/pgstb$ LOG: database system was interrupted; last known up at 2010-08-21 22:43:04 CST
LOG: entering standby mode
LOG: redo starts at 0/1000020
LOG: record with zero length at 0/10000B0
LOG: streaming replication successfully connected to primary
LOG: consistent recovery state reached at 0/2000000
LOG: database system is ready to accept read only connections
这时可以看到备库已经可以接受只读连接了。

    在主库上做一些操作:
osdba@osdba-laptop:/opt/pgstb$ psql -p 5432 -d postgres
psql (9.0beta4)
Type "help" for help.

postgres=# create table t (id int primary key,name varchar(20));
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pkey" for table "t"
CREATE TABLE
postgres=# insert into t (1,'xxxxxxx');
ERROR: syntax error at or near "1" at character 16
STATEMENT: insert into t (1,'xxxxxxx');
ERROR: syntax error at or near "1"
LINE 1: insert into t (1,'xxxxxxx');
                       ^
postgres=# insert into t values (1,'xxxxxxx');
INSERT 0 1
postgres=# insert into t values (2,'xxxxxxx');
INSERT 0 1
postgres=#

    然后在备库上看是否同步到了备库:
osdba@osdba-laptop:/opt/pgstb$ psql -p 5433 -d postgres
psql (9.0beta4)
Type "help" for help.
postgres=# \d
       List of relations
Schema | Name | Type | Owner
--------+------+-------+-------
public | t | table | osdba
(1 row)

postgres=# select * from t;
id | name
----+---------
  1 | xxxxxxx
  2 | xxxxxxx
(2 rows)

可以看到数据已经同步到了备库,基本上感觉不到延迟。

这篇文件也可以见我的blog: http://blog.chinaunix.net/u2/84422/showart.php?id=2305246,在blog中文章的格式可能更好看一些。

论坛徽章:
59
2015七夕节徽章
日期:2015-08-24 11:17:25ChinaUnix专家徽章
日期:2015-07-20 09:19:30每周论坛发贴之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38荣誉版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年纪念徽章
日期:2015-07-20 11:05:27IT运维版块每日发帖之星
日期:2015-07-20 11:05:34操作系统版块每日发帖之星
日期:2015-07-20 11:05:36程序设计版块每日发帖之星
日期:2015-07-20 11:05:40数据库技术版块每日发帖之星
日期:2015-07-20 11:05:432015年辞旧岁徽章
日期:2015-07-20 11:05:44
发表于 2010-08-21 23:44 |显示全部楼层
有时间我看看。检查一下。呵呵。

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-08 06:20:00数据库技术版块每日发帖之星
日期:2015-08-29 06:20:00数据库技术版块每日发帖之星
日期:2015-08-29 06:20:00数据库技术版块每日发帖之星
日期:2015-09-18 06:20:00数据库技术版块每周发帖之星
日期:2015-11-06 19:56:51数据库技术版块每日发帖之星
日期:2016-01-22 06:20:00数据库技术版块每日发帖之星
日期:2016-02-05 06:20:00
发表于 2010-10-21 18:22 |显示全部楼层
回复 1# osdba


    你好,我按你描述的步骤成功搭建了一个Standby环境
但是还有两个问题,在这里请教一下
1. 我的理解,Standby 应该提供主备切换的,我尝试把主机杀掉(Ctrl + C),检测备机是否会自动切换为主机,  结果是没有切换?
   我的问题,如何实现自动切换?
2. 看到recovery.conf 中有个trigger_file 选项,说是把备机切换为主机用的,但须手动 touch 该文件,有没有自动的方式?

论坛徽章:
3
数据库技术版块每日发帖之星
日期:2015-06-18 22:20:00数据库技术版块每日发帖之星
日期:2015-06-21 22:20:00数据库技术版块每日发帖之星
日期:2015-08-27 06:20:00
发表于 2010-10-22 09:29 |显示全部楼层
本帖最后由 osdba 于 2010-10-22 09:31 编辑

回复 3# asdf2110

两个问题的回答
1. 我的理解,Standby 应该提供主备切换的,我尝试把主机杀掉(Ctrl + C),检测备机是否会自动切换为主机,  结果是没有切换?
   我的问题,如何实现自动切换?
   PostgreSQL数据库本身并不提供自动切换的功能,如果想实现自动切换的功能需要使用第三方的HA软件来实现,如heartbeat、VCS(veritas)等等,或与pgpoolII3.0配置也能实现自动切换。

2. 看到recovery.conf 中有个trigger_file 选项,说是把备机切换为主机用的,但须手动 touch 该文件,有没有自动的方式?
   没有自动的方式。与第一个问题一样,需要用第三方的HA软件来实现。使用第三方的HA软件实现是很容易的事,第三方HA软件只需要新touch一个文件,就可以让standby切换成主库。

题外话,oracle数据库的standby也是这样的,当主库出现问题时,standby并不会自动变成主库,需要手工或第三方的HA软件做这个切换工作。

论坛徽章:
0
发表于 2010-10-26 11:07 |显示全部楼层
回复  asdf2110

两个问题的回答
1. 我的理解,Standby 应该提供主备切换的,我尝试把主机杀掉(Ctrl + ...
osdba 发表于 2010-10-22 09:29



   
能否给详细的文档,或者加上HA的软件的完整方案?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP