该搭建整套环境如下:
PostgreSQL 9.6 SUSE 环境搭建(一)
PostgreSQL 主从异步流复制配置(二)
PostgreSQL 主从异步、同步流复制配置(三)
在master上连接pocdb 数据库 ,基于配置二的节点状态
pocdb=# SELECT client_addr,application_name,sync_state FROM pg_stat_replication;
client_addr | application_name | sync_state
-------------+------------------+------------
10.10.56.17 | slave1 | async
10.10.56.19 | slave2 | async
(2 rows)
master有两个slave都是async(异步)流复制,现在修改slave1节点为sync(同步)流复制,修改master 节点的postgresql.conf中参数synchronous_standby_names
synchronous_standby_names = 'slave1'
postgres@clw-db1:~> /opt/pgsql-9.6/bin/pg_ctl -D /pgdata/9.6/poc/data/ reload
server signaled
查看master的复制信息:
pocdb=# SELECT client_addr,application_name,sync_state FROM pg_stat_replication;
client_addr | application_name | sync_state
-------------+------------------+------------
10.10.56.17 | slave1 | sync
10.10.56.19 | slave2 | async
(2 rows)
slave1已经修改为同步复制。
a. 隐式事务,同步slave宕机,事务挂起,slave恢复后写事务继续执行。
pocdb=# SELECT client_addr,application_name,sync_state FROM pg_stat_replication;
client_addr | application_name | sync_state
-------------+------------------+------------
10.10.56.17 | slave1 | sync
(1 row)
slave1为同步复制方式,当slave1宕机(kill -9),在master上执行查询可以执行,但写入的DML语句,将被block;
pocdb=# SELECT * FROM tbl;
id | ival | cval
----+------+------
1 | 1 | A
2 | 20 | B
(2 rows)
pocdb=# INSERT INTO tbl (ival,cval) VALUES ( 4,NULL);
恢复slave1之后,master上的事务将继续执行:
恢复slave:
postgres@clw-db2:~> /opt/pgsql-9.6/bin/pg_ctl -D /pgdata/9.6/poc/data/ start
server starting
master上的事务:
pocdb=# INSERT INTO tbl (ival,cval) VALUES ( 4,NULL);
INSERT 0 1
pocdb=# SELECT * FROM tbl;
id | ival | cval
----+------+------
1 | 1 | A
2 | 20 | B
4 | 4 |
(3 rows)
在同步复制的slave节点上查询
pocdb=# SELECT * FROM tbl;
id | ival | cval
----+------+------
1 | 1 | A
2 | 20 | B
4 | 4 |
(3 rows)
b. 显式事务,在slave宕机的情况下,提交的事务会本地提交,slave恢复后会将master上本地提交的事务同步到slave,rollback的事务在slave宕机时不受影响。
显式本地提交事务:
pocdb=# BEGIN;
BEGIN
pocdb=# INSERT INTO tbl (ival,cval) VALUES (5,NULL);
INSERT 0 1
pocdb=# COMMIT;
^CCancel request sent
WARNING: canceling wait for synchronous replication due to user request
DETAIL: The transaction has already committed locally, but might not have been replicated to the standby.
COMMIT
pocdb=#
显式本地ROLLBACK事务:
pocdb=# BEGIN;
BEGIN
pocdb=# INSERT INTO tbl (ival,cval) VALUES (10,'f');
INSERT 0 1
pocdb=# ROLLBACK;
ROLLBACK
pocdb=#
在slave上查询:
postgres@clw-db2:~> /opt/pgsql-9.6/bin/psql pocdb
psql (9.6.8)
Type "help" for help.
pocdb=# SELECT * FROM tbl;
id | ival | cval
----+------+------
1 | 1 | A
2 | 20 | B
4 | 4 |
6 | 5 |
(4 rows)
当异步复制slave宕机,master读写不受影响,恢复后可即时同步到最新数据:
pocdb=# SELECT * FROM tbl;
id | ival | cval
----+------+------
1 | 1 | A
2 | 20 | B
4 | 4 |
6 | 5 |
(4 rows)