使用PostgreSQL 11.3 建立两个节点:node1 和 node2; 配置主从流复制,而后作手动切换(failover)。为了配置过程简单,两个节点在同一台物理机器上。node
首先创建主从同步流复制,起初,node1做为主节点(Primary),node2做为从节点(Standby)。sql
接下来,模拟主节点(node1)没法工做,把从节点(node2)手动切换成主节点。而后把原来的主节点(node1)做为从节点加入系统。 此时,node2是主 (Primary), node1是从(Standby)。数据库
最后,模拟主节点(node2)没法工做,把从节点(node1)手动切换成主节点。而后把node2做为从节点加入系统。 此时,node1是主 (Primary), node2是从(Standby)。bash
上级目录是:app
/Users/tom
两个子目录,testdb113,testdb113b, 分别属于两个节点, node1, node2:dom
testdb113 --> node1 testdb113b --> node2
mkdir testdb113 initdb -D ./testdb113 pg_ctl -D ./testdb113 start
CREATE ROLE replicauser WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'abcdtest';
mkdir ./testdb113/archive
#for the primary wal_level = replica synchronous_commit = remote_apply archive_mode = on archive_command = 'cp %p /Users/tom/testdb113/archive/%f' max_wal_senders = 10 wal_keep_segments = 10 synchronous_standby_names = 'pgslave001' #for the standby hot_standby = on
host replication replicauser 127.0.0.1/32 md5 host replication replicauser ::1/128 md5
standby_mode = 'on' recovery_target_timeline = 'latest' primary_conninfo = 'host=localhost port=6432 user=replicauser password=abcdtest application_name=pgslave001' restore_command = 'cp /Users/tom/testdb113b/archive/%f %p' trigger_file = '/tmp/postgresql.trigger.5432'
mkdir testdb113b pg_basebackup -D ./testdb113b chmod -R 700 ./testdb113b
#for the primary port = 6432 wal_level = replica synchronous_commit = remote_apply archive_mode = on archive_command = 'cp %p /Users/tom/testdb113b/archive/%f' max_wal_senders = 2 wal_keep_segments = 10 synchronous_standby_names = 'pgslave001' #for the standby hot_standby = on
mkdir ./testdb113b/archive
standby_mode = 'on' recovery_target_timeline = 'latest' primary_conninfo = 'host=localhost port=5432 user=replicauser password=abcdtest application_name=pgslave001' restore_command = 'cp /Users/tom/testdb113/archive/%f %p' trigger_file = '/tmp/postgresql.trigger.6432'
pg_ctl -D ./testdb113 restart
pg_ctl -D ./testdb113b start
psql -d postgres
postgres=# create table test ( id int, name varchar(100)); CREATE TABLE postgres=# insert into test values(1,'1'); INSERT 0 1
psql -d postgres -p 6432
postgres=# select * from test; id | name ----+------ 1 | 1 (1 row) postgres=# insert into test values(1,'1'); ERROR: cannot execute INSERT in a read-only transaction postgres=#
pg_ctl -D ./testdb113 stop
Ruis-MacBook-Air:tom$ psql -d postgres psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
Ruis-MacBook-Air:~ tom$ psql -d postgres -p 6432 psql (11.3) Type "help" for help. postgres=# insert into test values(1,'1'); ERROR: cannot execute INSERT in a read-only transaction postgres=#
touch /tmp/postgresql.trigger.6432
postgres=# insert into test values(2,'2');
mv recovery.done recovery.conf
pg_ctl -D ./testdb113 start
postgres=# insert into test values(2,'2'); INSERT 0 1 postgres=#
postgres=# select * from test; id | name ----+------ 1 | 1 2 | 2 (2 rows)
pg_ctl -D ./testdb113b stop
Ruis-MacBook-Air:~ tom$ psql -d postgres -p 6432 psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
Ruis-MacBook-Air:~ tom$ psql -d postgres psql (11.3) Type "help" for help. postgres=# insert into test values(3,'3'); ERROR: cannot execute INSERT in a read-only transaction postgres=#
touch /tmp/postgresql.trigger.5432
postgres=# insert into test values(3,'3');
mv recovery.done recovery.conf
pg_ctl -D ./testdb113b start
postgres=# insert into test values(3,'3'); INSERT 0 1
postgres=# select * from test; id | name ----+------ 1 | 1 2 | 2 3 | 3 (3 rows)
当主节点不能工做时,须要把一个从节点提高成为主节点。 若是是手工方式提高,可使用trigger文件,也可使用命令'pg_ctl promote' 。socket
目前也有不少种自动化监控和切换的方案,在网上都能搜索到。或者,能够本身动手写一个自动化监控和切换的方案。post