主從復制
1. 基於文件的日志傳送
創建一個高可用性(HA)集群配置可采用連續歸檔,集群中主服務器工作在連續歸檔模式下,備服務器工作在連續恢復模式下(1台或多台可隨時接管主服務器),備持續從主服務器讀取WAL文件。
連續歸檔不需要對數據庫表做任何改動,可有效降低管理開銷,對主服務器的性能影響也相對較低。
直接從一個數據庫服務器移動WAL記錄到另一台服務器被稱為日志傳送,PostgreSQL通過一次一文件(WAL段)的WAL記錄傳輸實現了基於文件的日志傳送。
- 日志傳送所需的帶寬取根據主服務器的事務率而變化;
- 日志傳送是異步的,即WAL記錄是在事務提交后才被傳送,那么在一個窗口期內如果主服務器發生災難性的失效則會導致數據丟失,還沒有被傳送的事務將會被丟失;
- 數據丟失窗口可以通過使用參數archive_timeout進行限制,可以低至數秒,但同時會增加文件傳送所需的帶寬。
2. 流復制
PostgreSQL在9.x之后引入了主從的流復制機制,所謂流復制,就是備服務器通過tcp流從主服務器中同步相應的數據,主服務器在WAL記錄產生時即將它們以流式傳送給備服務器,而不必等到WAL文件被填充。
- 默認情況下流復制是異步的,這種情況下主服務器上提交一個事務與該變化在備服務器上變得可見之間客觀上存在短暫的延遲,但這種延遲相比基於文件的日志傳送方式依然要小得多,在備服務器的能力滿足負載的前提下延遲通常低於一秒;
- 在流復制中,備服務器比使用基於文件的日志傳送具有更小的數據丟失窗口,不需要采用archive_timeout來縮減數據丟失窗口;
- 將一個備服務器從基於文件日志傳送轉變成基於流復制的步驟是:把recovery.conf文件中的primary_conninfo設置指向主服務器;設置主服務器配置文件的listen_addresses參數與認證文件即可。
一、主從環境
1. 操作系統
CentOS-7-x86_64
2. PostgresSQL版本
PostgreSQL 9.6
3. 主機
主機名 | IP | 端口 | 角色 |
pg_master | 192.168.159.150 | 5432 | 主庫 |
pg_slave | 192.168.159.151 | 5432 | 從庫 |
二 、主庫配置
三.主庫配置
1. 使用postgres用戶登陸數據庫,創建復制用戶
#需要一個賬號進行主從同步
postgres=#create role replica login replication encrypted password 'replica';
2. 認證文件pg_hba.conf
#配置從庫可以采用replica賬號進行同步
[root@psql_master ~]#vim /var/lib/pgsql/9.6/data/pg_hba.conf
host replication replica 192.168.159.0/24 md5
3. 主庫配置文件postgresql.conf
[root@psql_master ~]# vim /var/lib/pgsql/9.6/data/postgresql.conf
listen_addresses = '*'
max_connections = 1000
wal_level = replica
max_wal_senders = 1
wal_keep_segments = 64
archive_mode = on
archive_command = 'cp %p /var/lib/pgsql/pg_archive/%f'
wal_log_hints = on
full_page_writes = on
hot_standby = on
4.創建pg_archive目錄
mkdir -p /var/lib/pgsql/pg_archive
chown -R postgres:postgres /var/lib/pgsql/pg_archive
5.配置.pgpass
su - postgres
vim ~/.pgpass
192.168.159.150:5432:replication:replica:replica
192.168.159.151:5432:replication:replica:replica
6.配置recovery文件(主庫recovery.done,從庫recovery.conf)
vim /var/lib/pgsql/9.6/data/recovery.done
standby_mode = on
primary_conninfo = 'host=192.168.159.151 port=5432 user=replica password=replica'
recovery_target_timeline = 'latest'
7.權限變更
chown -R postgres:postgres /var/lib/pgsql/9.6/data/
8. 重啟服務
#同時注意打開防火牆端口打開
[root@psql_master ~]# systemctl restart postgresql-9.6
三、從庫配置
先清空data目錄(默認/var/lib/pgsql/9.6/data)
cd /var/lib/pgsql/9.6/data
rm -fr *
1. 基礎備份(主庫需索表,只讀不能寫)
[root@pg_slave ~]# pg_basebackup -h 192.168.159.150 -p 5432 -U replica -F p -P -D /var/lib/pgsql/9.6/data/
#-h,主庫主機,-p,主庫服務端口;
#-U,復制用戶;
#-F,p是默認輸出格式,輸出數據目錄和表空間相同的布局,t表示tar格式輸出;
#-P,同--progress,顯示進度;
#-D,輸出到指定目錄;
#因為主庫采用的是md5認證,這里需要密碼認證。
2. 備份目錄權限
#基於root賬號做的基礎備份,需要將相關目錄文件的權限變更
[root@pg_slave ~]# chown -R postgres:postgres /var/lib/pgsql/9.6/data/
3.修改recovery文件
mv recovery.done recovery.conf
vim recovery.conf
standby_mode = on
primary_conninfo = 'host=192.168.159.150 port=5432 user=replica password=replica'
recovery_target_timeline = 'latest'
4.創建pg_archive目錄
mkdir -p /var/lib/pgsql/pg_archive
chown -R postgres:postgres /var/lib/pgsql/pg_archive
5.配置.pgpass
su - postgres
vim ~/.pgpass
192.168.159.150:5432:replication:replica:replica
192.168.159.151:5432:replication:replica:replica
6.啟動服務
systemctl start postgresql-9.6
四、驗證主從
1.查看進程
1.1主庫sender進程
1.2從庫receive進程
2.在主庫上查看復制狀態
postgres=# \x
postgres=# select * from pg_stat_replication;
#pid,sender進程;
#usesysid,復制用戶id;
#usename,復制用戶名;
#application_name,復制進程名;
#client_addr,從庫客戶端地址;
#client_hostname,從庫客戶端名;
#client_port,從庫客戶端port;
#backend_start,主從復制開始時間;
#backend_xmin,當前后端的xmin范圍,由備機提供;
#state,同步狀態,startup:連接中;catchup:同步中;streaming:同步; #sent_location,主傳送wal的位置;
#write_location,從接收wal的位置;
#flush_location,從刷盤的wal位置;
#replay_location,從同步到數據庫的wal位置;
#sync_priority,同步優先級,0表示異步;1~?表示同步,數字越小優先級越高; #sync_state, async:異步;sync:同步;potential;當前是異步,但可能升級到同步模式;
#另外,”select pg_is_in_recovery();“命令也可以查看主從狀態,false是主,true為從。
3.建表寫入數據測試
主庫上建一個測試庫,測試表,然后寫入數據,在從庫上看是否有主庫寫入的測試數據。
五、主備切換
主數據庫是讀寫的,備數據庫是只讀的。當主數據庫宕機了,可以通過pg_controldata命令將從庫提升為主庫(將只讀模式變成讀寫),實現一些基本的HA應用。也可以通過建立觸發文件提升為主庫,不推薦。命令快捷不容易出錯。
1.查看/var/lib/pgsql/9.6/data復制狀態
主庫
[root@pg_master ~]# pg_controldata /var/lib/pgsql/9.6/data/
pg_control version number: 960
Catalog version number: 201608131
Database system identifier: 6362107256088627972
Database cluster state: in production
從庫
pg_control version number: 960
Catalog version number: 201608131
Database system identifier: 6362107256088627972
Database cluster state: in archive recovery
2.主庫故障
[root@pg_master ~]# systemctl stop postgresql-9.6
[root@pg_master ~]# pg_controldata /var/lib/pgsql/9.6/data
pg_control version number: 960
Catalog version number: 201608131
Database system identifier: 6362107256088627972
Database cluster state: shut down
3.提升從庫為主庫(在從庫上執行)
[root@pg_slave ~]# su - postgres -c "pg_ctl promote"
server promoting
4.查看從庫日志,狀態及進程
[root@pg_master ~]# cat /var/lib/pgsql/9.6/data/pg_log/postgresql-Mon.log
[root@pg_master ~]# pg_controldata /var/lib/pgsql/9.6/data
pg_control version number: 960
Catalog version number: 201608131
Database system identifier: 6362107256088627972
Database cluster state: in production
[root@pg_master ~]# ps -ef|grep postgres
postgres 34461 1133 0 Mar05 ? 00:00:00 postgres: wal sender process replica 192.168.159.150(49947) streaming 0/F006670
5.恢復pg_master(192.168.159.150),然后作為新的從庫,在恢復之前可以往新主庫寫入數據,然后啟用服務,數據會同步至新的從庫。
[root@pg_master ~]# cd /var/lib/pgsql/9.6/data
[root@pg_master ~]# mv recovery.done reconvery.conf
[root@pg_master ~]# systemctl start postgresql-9.6
[root@pg_master ~]# ps -ef|grep postgres
postgres 32502 24304 0 Mar05 ? 00:00:15 postgres: wal receiver process streaming 0/F006750