流復(fù)制分為異步和同步復(fù)制,異步:故名意思主庫不會管從庫是否落盤罐旗,應(yīng)用完成,主庫也會提交事務(wù)唯蝶。而同步復(fù)制:主庫會等待從庫九秀,數(shù)據(jù)回放是否完成,或者是否落盤等粘我,在流復(fù)制強同步的情況下鼓蜒,主庫可能會陷入等待,無法提交事務(wù)征字。
環(huán)境介紹
角色 | IP | 服務(wù) |
---|---|---|
leader | 172.22.138.218/20 | postgresql v14 |
standby1 | 172.22.138.219/20 | postgresql v14 |
standby2 | 172.22.138.220/20 | postgresql v14 |
異步流復(fù)制
Leader節(jié)點的配置
首先在三個節(jié)點上搭建好PostgreSQL都弹。
如果不知道怎么搭建的可以查看我另一篇文章《PostgreSQL-Linux環(huán)境源碼編譯安裝》
1.在172.22.138.218要做主庫的節(jié)點創(chuàng)建復(fù)制用戶
root # su - postgres
postgres # psql
...
postgres=# create user replica with password 'replica';
postgres=# alter user replica replication;
2.編輯172.22.138.218節(jié)點的訪問控制文件,在pg_hba.conf中增加復(fù)制用戶的訪問權(quán)限匙姜。
postgres # cd /data/pgsql/data
postgres # vim pg_hba.conf
# 注意畅厢!下方IP地址的子網(wǎng)掩碼根據(jù)實際情況配置
...
host replication all 172.22.138.219/20 trust
host replication all 172.22.138.220/20 trust
...
3.修改172.22.138.218的postgresql.conf配置文件,請確保配置文件中的目錄都正確或都存在氮昧,并確保屬主屬組的權(quán)限為postgres或详。
postgres # vim postgresql.conf
...
port = '5432'
listen_addresses = '*
max_connections = '1000'
max_locks_per_transaction = '64'
max_prepared_transactions = '0'
max_replication_slots = '10'
max_wal_senders = '10'
max_worker_processes = '8'
track_commit_timestamp = 'off'
wal_sender_timeout = 60s
wal_keep_size = '1600MB'
wal_level = 'replica'
wal_log_hints = 'on'
hot_standby = 'on'
archive_mode=on
archive_command='cp %p //data/pgsql/archive/%f'
archive_timeout=1800
hba_file = '/data/pgsql/data/pg_hba.conf'
ident_file = '/data/pgsql/data/pg_ident.conf'
logging_collector = on
log_directory = '/data/pgsql/log'
4.重啟postgresql,使配置文件生效郭计。
root # systemctl restart postgresql
Standby節(jié)點的配置
1.停止所有standby節(jié)點的postgresql進程
root # systemctl stop postgresql
2.清理standby的pgsql數(shù)據(jù)目錄
postgres # mkdir /tmp/data
postgres # mv /data/pgsql/data/* /tmp/data
3.在standby節(jié)點通過物理備份工具pg_basebackup,將leader節(jié)點的數(shù)據(jù)copy到standby節(jié)點
postgres # pg_basebackup -D /data/pgsql/data/ -h 172.22.138.218 -p 5432 -U replica -X stream -Pv -R
4.修改standby節(jié)點的postgresql.conf文件椒振,在primary_conninfo選項加入節(jié)點標(biāo)識application_name昭伸。
postgres # vim postgresql.conf
...
primary_conninfo = '... application_name=standby1 ....'
primary_conninfo = '... application_name=standby2 ....'
5.啟動standby節(jié)點的postgresql
root # systemctl start postgresql
6.查看leader節(jié)點和standby節(jié)點的復(fù)制狀態(tài)
# leader
postgres=# select * from pg_stat_replication;
+-------+----------+---------+------------------+----------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------+-----------+------------+---------------+------------+-------------------------------+
| pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state | reply_time |
+-------+----------+---------+------------------+----------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------+-----------+------------+---------------+------------+-------------------------------+
| 12368 | 16384 | replica | standby1 | 172.22.138.219 | | 47170 | 2024-08-15 10:23:36.860733+08 | | streaming | 0/DC000000 | 0/DC000000 | 0/DC000000 | 0/DC000000 | | | | 0 | async | 2024-08-15 11:10:18.855529+08 |
| 11101 | 16384 | replica | standby2 | 172.22.138.218 | | 55800 | 2024-08-15 09:57:31.073827+08 | | streaming | 0/DC000000 | 0/DC000000 | 0/DC000000 | 0/DC000000 | | | | 0 | async | 2024-08-15 11:10:19.992588+08 |
+-------+----------+---------+------------------+----------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+------------+-----------+-----------+------------+---------------+------------+-------------------------------+
# standby
postgres=# select * from pg_stat_wal_receiver;
-[ RECORD 1 ]---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid | 18720
status | streaming
receive_start_lsn | 0/DB000000
receive_start_tli | 3
written_lsn | 0/DC000000
flushed_lsn | 0/DC000000
received_tli | 3
last_msg_send_time | 2024-08-15 11:11:08.623733+08
last_msg_receipt_time | 2024-08-15 11:11:08.623328+08
latest_end_lsn | 0/DC000000
latest_end_time | 2024-08-15 11:09:52.14472+08
slot_name | pa_pg_2
sender_host | 172.22.138.218
sender_port | 5432
conninfo | user=replica dbname=replication host=172.22.138.218 port=5432 application_name=standby1 ....
同步流復(fù)制
同步流復(fù)制,相較于異步澎迎,只需要在搭建流復(fù)制的時候庐杨,在本文檔的第一階段的Leader節(jié)點配置環(huán)節(jié)的第三步选调,修改leader節(jié)點postgresql.conf文件的時候加入兩個參數(shù)。synchronous_commit和synchronous_standby_names灵份。
synchronous_commit
這個參數(shù)主要是為了控制仁堪,當(dāng)一個事務(wù)寫入后,判斷一個事務(wù)是否已經(jīng)正確提交填渠,在什么狀態(tài)下提交的弦聂,參數(shù)值分為以下幾種。
off:當(dāng)pgsql事務(wù)提交的時候氛什,不需要等待wal buffer中的數(shù)據(jù)莺葫,是否已經(jīng)刷盤到wal log,立即返回給客戶端枪眉,事務(wù)提交成功捺檬。這種情況數(shù)據(jù)庫因為不需要等待事務(wù)是否落盤,所以性能最佳贸铜,但相對會有數(shù)據(jù)丟失的風(fēng)險堡纬。如果在數(shù)據(jù)提交后,wal buffer沒有刷盤完成到wal log蒿秦,數(shù)據(jù)庫此時崩潰烤镐,可能會丟失數(shù)據(jù)。
local:當(dāng)事務(wù)提交時渤早,確認數(shù)據(jù)落盤职车,寫入到了本地主庫的數(shù)據(jù)文件,本地持久化成功鹊杖,返回客戶端已提交悴灵,但是不會管備庫是否接收和落盤。此種情況相較于off骂蓖,要安全一些积瞒,保證了主庫數(shù)據(jù)安全的情況下,還能保留一定的性能登下。
remote_write:對于安全和性能茫孔,相對來說比較平衡,它保證了事務(wù)在主庫實現(xiàn)持久化后被芳,至少有一個同步的從庫缰贝,接收并且寫入了wal log到文件系統(tǒng)當(dāng)中,當(dāng)時不保證從庫wal log是否刷盤和應(yīng)用畔濒。隨后對客戶端返回已提交剩晴。
remote_apply:較高的安全性,較低的性能,它保證了事務(wù)在主庫實現(xiàn)持久化后赞弥,至少有一個同步的從庫毅整,接收并且寫入了wal log到文件系統(tǒng),并且回放完成绽左,應(yīng)用到了數(shù)據(jù)庫中悼嫉,但是沒有保證數(shù)據(jù)是否刷盤。
on:最高級別的數(shù)據(jù)持久性保障拼窥,較差的性能戏蔑,不但保證了主庫本地數(shù)據(jù)的持久性,如果是在一主兩從的流復(fù)制中闯团,還需要至少一個從庫已經(jīng)持久化刷盤完成(這個需要配置synchronous_standby_names)辛臊,最后才可以返回給客戶端已提交。這就是我們前面說到的房交,強同步流復(fù)制彻舰,當(dāng)然如果從庫一直沒有提交,主庫就會夯住候味,處于一直等待刃唤。
synchronous_standby_names
這個參數(shù),主要是在同步復(fù)制配置過程中白群,比較重要的一個參數(shù)尚胞,前面提到了當(dāng)synchronous_commit,配置不同的值帜慢,需要等待從庫刷盤笼裳、接收wal log等幾種情況,而相關(guān)需要它等待的從庫就在這里配置粱玲。配置方式也是多種方式躬柬。
synchronous_standby_names = 'standby1':配置一個表示,只需要等待standby1這一個從庫抽减,等待到哪個地步由synchronous_commit的具體參數(shù)控制允青。
synchronous_standby_names = 'FIRST 1 (standby1,standby2)':FIRST 1表示最多等待幾個從庫,這里表示最多等待一個卵沉,優(yōu)先級最高的為standby1颠锉,表示優(yōu)先等待standby1這一個從庫,如果standby1不可用了史汗,那系統(tǒng)將自動降級等待standby2琼掠。
synchronous_standby_names = 'ANY 1 (standby1,standby2)':ANY 1表示從standby1和standby2兩個節(jié)點,等待任意一個即可停撞,沒有所謂的優(yōu)先級瓷蛙,任何一個等待完成都算成功。