postgresql同步流复制的Hot Standby

Postgresql的流复制是异步的,异步的缺点是Standby上的数据落后于主库上的数据,如果使用Hot Standby做读写分离,就会存在数据一致性的问题,对于一些一致性高的应用来说是不可接受的。所以PG从9.1之后提供了同步流复制的架构。同步复制要求在数据写入Standby数据后,事务的commit才返回,所以Standby库出现问题时,会导致主库被Hang住。解决这个问题的方法是启动两个standby数据库,这两个Standby数据库只有有一个是正常的,就不会让主库Hang住。所以在实际应用中,同步流复制,总是有一个主库和2个以上的Standby库。

   

     实现同步复制功能主要是在主库上配置参数”synchronous_standby_names",这个参数指定多个Standby的名称,各个名称之间通过逗号分隔,而Standby名称是在Standby连接到主库时,由连接参数“application_name"指定的。要使用同步复制,在Standby数据库中,recovery.conf里的primary_conninfo一定要指定连接参数”application_name"。

 

1、配置环境:

                                                                示例环境

主机名

IP地址

角色

系统版本

数据目录

pg版本

pg-1

10.0.2.60

主库

RedHat6.4

/usr/local/postgresql-9.4.4/data

9.4

pg-2

10.0.2.61

standby

RedHat6.4

/usr/local/postgresql-9.4.4/data

9.4

pg-3

10.0.2.62

standby

RedHat6.4

/usr/local/postgresql-9.4.4/data

9.4

 

2、1)在主库上修改pg_hba.conf:

host    replication     postgre        10.0.2.0/24             md5

    

   2)修改postgresql.conf :

max_wal_senders = 4

wal_level = hot_standby 

 hot_standby = on 

不设置此项不能访问,如下:

[postgre@pg-2 postgresql-9.4.4]$ psql  postgres

psql: FATAL:  the database system is starting up

 

  3)指定同步复制的Standby的名称,修改postgresql.conf:

synchronous_standby_names ='standby01,standby02'

   注:此处设置的'standby01,standby02'就是在Standby数据库中配置连接参数“application_name”。

 

 3、在备库pg-2上配置:

   1)修改recovery.conf:

[postgre@pg-2 data]$ vi recovery.conf 

 

standby_mode = 'on'

primary_conninfo = 'application_name=standby01 user=postgre password=postgre host=10.0.2.60 port=5432sslmode=disable sslcompression=1'

 

启动standby:

[postgre@pg-2 postgresql-9.4.4]$ pg_ctl  start  -D/usr/local/postgresql-9.4.4/data  -l logfile

    在pg-3上配置:

[postgre@pg-3 data]$ cat recovery.conf 

standby_mode = 'on'

primary_conninfo = 'application_name=standby02 user=postgre password=postgre host=10.0.2.60 port=5432sslmode=disable sslcompression=1'

 

 启动standby:

[postgre@pg-3 data]$ pg_ctl start  -D/usr/local/postgresql-9.4.4/data  -l logfile 

 

4、在主库上启动同步复制:

[postgre@pg-1 data]$ pg_ctl reload -D/usr/local/postgresql-9.4.4/data 

server signaled

 

5、测试:

主库上插入数据:

[postgre@pg-1 data]$ psql postgres

psql (9.4.4)

Type "help" for help.

 

postgres=# insert into hotstandby values (3,'003');

INSERT 0 1

postgres=# insert into hotstandby values (4,'004');

INSERT 0 1

postgres=# insert into hotstandby values (5,'005');

INSERT 0 1

postgres=# insert into hotstandby values (6,'006');

INSERT 0 1

postgres=# insert into hotstandby values (7,'007');

INSERT 0 1

postgres=# select * from hotstandby ;

 id | name 

----+------

  1 | 001

  2 | 002

  3 | 003

  4 | 004

  5 | 005

  6 | 006

  7 | 007

(7 rows)

备库:

pg-2:

postgres=# select * from hotstandby ;

 id | name 

----+------

  1 | 001

  2 | 002

  3 | 003

  4 | 004

  5 | 005

  6 | 006

  7 | 007

(7 rows)

pg-3:

postgres=# select * from hotstandby;

 id | name 

----+------

  1 | 001

  2 | 002

  3 | 003

  4 | 004

  5 | 005

  6 | 006

  7 | 007

(7 rows)

 

6、故障模拟:

1)关掉一台备库,看主库是否正常工作:

关掉pg-2:

[postgre@pg-2 postgresql-9.4.4]$ pg_ctl  stop   -D /usr/local/postgresql-9.4.4/data  

waiting for server to shut down.... done

server stopped

主库:

postgres=# insert into hotstandby values (9,'009');

INSERT 0 1

postgres=# 

pg-3:

postgres=# select * from hotstandby;

 id | name 

----+------

  1 | 001

  2 | 002

  3 | 003

  4 | 004

  5 | 005

  6 | 006

  7 | 007

  8 | 008

  9 | 009

(9 rows)

重启pg-2后:

[postgre@pg-2 postgresql-9.4.4]$ psql postgres

psql (9.4.4)

Type "help" for help.

 

postgres=# select * from hotstandby ;

 id | name 

----+------

  1 | 001

  2 | 002

  3 | 003

  4 | 004

  5 | 005

  6 | 006

  7 | 007

  8 | 008

  9 | 009

(9 rows)

 

可见,当一台standby损坏时,主库是不受影响的。

 

2)同时关掉两台standby:

[postgre@pg-2 postgresql-9.4.4]$ pg_ctl stop     

waiting for server to shut down.... done

server stopped

[postgre@pg-3 data]$ pg_ctl  stop

waiting for server to shut down.... done

server stopped

 

在主库操作:

postgres=# select * from hotstandby;

 id | name 

----+------

  1 | 001

  2 | 002

  3 | 003

  4 | 004

  5 | 005

  6 | 006

  7 | 007

  8 | 008

  9 | 009

(9 rows)

 

postgres=# insert into hotstandby values (10,'010');

 

非跟新操作都是正常的,但更新操作就不hang住了。此时启动一台standby

[postgre@pg-2 postgresql-9.4.4]$ pg_ctl start  

server starting

原本hang住的可以继续了:

postgres=# insert into hotstandby values (10,'010');

INSERT 0 1

 

7、检查同步流复制的情况:

postgres=# select pid,state,client_addr,sync_priority,sync_state frompg_stat_replication;

  pid  |   state   | client_addr | sync_priority |sync_state 

-------+-----------+-------------+---------------+------------

 11143 | streaming | 10.0.2.61   |            1 | sync

 11179 | streaming | 10.0.2.62   |            2 | potential

(2 rows)

 

由上面可知pg-2的优先级是1,pg-3的优先级是2,这个优先级是由synchronous_standby_names的参数顺序决定的。目前主数据库与pg-2是处于同步"SYNC",而pg-3的状态为“potential",表示它是一个潜在的同步standby,当pg-2损坏时,pg-3会切换到同步状态。

[postgre@pg-2 pg_log]$ pg_ctl  stop

waiting for server to shut down.... done

server stopped

postgres=# select pid,state,client_addr,sync_priority,sync_state frompg_stat_replication;

  pid  |   state   | client_addr | sync_priority |sync_state 

-------+-----------+-------------+---------------+------------

 11179 | streaming | 10.0.2.62   |            2 | sync

(1 row)

再次启动pg-2:

[postgre@pg-2 pg_log]$ pg_ctl  start    -D/usr/local/postgresql-9.4.4/data   

server starting

postgres=# select pid,state,client_addr,sync_priority,sync_state frompg_stat_replication;

  pid  |   state   | client_addr | sync_priority |sync_state 

-------+-----------+-------------+---------------+------------

 11213 | streaming | 10.0.2.61   |            1 | sync

 11179 | streaming | 10.0.2.62   |            2 | potential

(2 rows)

 

你可能感兴趣的:(postgresql)