使用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