Linux下PostgreSQL主備環境搭建和切換
1. 概念
資料庫熱備:資料庫熱備是指為主資料庫的建立、維護和監控一個或多個備用資料庫,它們時刻處於開機狀態,同主機保持同步。當主機失靈時,可以隨時啟用熱備資料庫來代替,以保護資料不受故障、災難、錯誤和崩潰的影響。
流複製(streaming replication):PostgreSQL提供的一種伺服器間的資料複製方式。這種方式下,後備伺服器連線到主伺服器,主伺服器則在 WAL 記錄產生時即將它們以流式傳送給後備伺服器而不必等到 WAL 檔案被填充。
2. 實驗環境
普通PC兩臺
作業系統:Linux CentOS release 6.6
軟體:PostgreSQL 10.0
3. 實驗過程
3.1 實驗準備
兩臺虛擬機器上都安裝了PostgreSQL 10.0,它們的安裝目錄是:/opt/postgresql10/
在/etc/profile 中新增如下幾行:
export PATH=/opt/postgresql10/bin:$PATH
export LD_LIBRARY_PATH=/opt/postgresql10/lib:$LD_LIBRARY_PATH
export PGDATA=/opt/postgresql10/data
本實驗環境中,主機的IP地址為10.33.45.101,備機IP 地址為 10.33.45.102。
3.2 搭建PostgreSQL 主備環境。
3.2.1 主節點上的操作
1. 確保服務已經啟動。執行命令:
su postgresql
切換使用者,並執行:
pg_ctl start -D $PGDATA
啟動服務。
2. 建立用於流複製的使用者。執行命令:
psql -h 127.0.0.1 -p 5432 -U postgres
進入控制檯,並執行如下語句建立使用者:
create user repuser with login replication password 123456;
3. 修改pg_hba.conf 檔案,新增如下內容,允許兩臺計算機上的複製使用者和超級使用者登入:
host replication repuser 10.33.45.101/32 md5
host replication repuser 10.33.45.102/32 md5
host all postgres 10.33.45.101/32 trust
host all postgres 10.33.45.102/32 trust
4. 在主節點的 postgresql.conf 中設定這些引數:
max_wal_senders =10
wal_level = replica
wal_log_hints = on
log_connections = on
wal_receiver_status_interval = 2s
hot_standby_feedback = on
5. 重啟主節點:
pg_ctl restart -D $PGDATA
3.2.2 備節點上的操作
1. 確保服務是停止的:
su postgresql
切換使用者,並執行:
pg_ctl stop -D $PGDATA
關閉服務。
2. 首先刪除備節點中的資料目錄 $PGDATA 中的檔案:
cd $PGDATA
rm –rf *
然後執行:
pg_basebackup -d "hostaddr=10.33.45.101 port=5432 user=repuser password=123456" -D $PGDATA -v -Fp –Xs
3. 基礎備份完成後,修改備節點的 postgresql.conf 檔案,設定:
hot_standby = on
4. 將 /opt/postgresql10/share/ 中的 recovery.conf.sample 拷貝到 $PGDATA 下,重新命名為 recovery.conf:
cp /opt/postgresql10/share/recovery.conf.sample $PGDATA/recovery.conf
並設定如下引數:
recovery_target_timeline = 'latest'
standby_mode = on
primary_conninfo = 'host=10.33.45.101 port=5432 user=repuser password=123456'
trigger_file = 'tgfile’
5. 啟動備節點服務:
pg_ctl stop -D $PGDATA
3.3 主備環境檢測
1. 在主節點上建立一個表,並插入資料:
postgres=# create table student (id int, name text);
CREATE TABLE
postgres=# insert into student (id, name) values (1,'tom');
INSERT 0 1
2. 在備節點上檢測:
postgres=# select * from student;
id | name
----+------
1 | tom
主節點資料同步到了備機。
同時,在備節點上寫資料會失敗:
postgres=# insert into student (id, name) values (2,'amy');
ERROR: cannot execute INSERT in a read-only transaction
3.4 主備環境的切換
1. 啟用備節點,使之成為新的主結點:
pg_ctl promote -D $PGDATA
結果是:
waiting for server to promote........ done
server promoted
2. 檢視新主節點的狀態:
postgres=# pg_controldata | grep cluster
Database cluster state: in production
插入一條資料:
postgres=# insert into student (id, name) values (2,'amy');
INSERT 0 1
3. 停止舊的主結點:
pg_ctl stop -m fast -D $PGDATA
結果:
waiting for server to shut down.... done
server stopped
4. 在停止的舊主結點上執行:
pg_rewind --target-pgdata $PGDATA --source-server='host=10.33.45.102 port=5432 user=postgres dbname=postgres' -P
結果如下:
connected to server
servers diverged at WAL location 0/2B000230 on timeline 4
rewinding from last common checkpoint at 0/2A000098 on timeline 4
reading source file list
reading target file list
reading WAL in target
need to copy 57 MB (total source directory size is 143 MB)
58749/58749 kB (100%) copied
creating backup label and updating control file
syncing target data directory
Done!
表示從新主節點上成功獲取WAL日誌。
5. 重新配置舊主結點的 recovery.conf:
standby_mode = on
primary_conninfo = 'hostaddr=10.33.45.102 port=5432 user=repuser password=123456'
6. 在舊主結點上執行下面的命令,重新啟動該節點:
pg_ctl start -D $PGDATA
7. 在舊主結點上驗證:
postgres=# insert into student (id, name) values (3,'lily');
ERROR: cannot execute INSERT in a read-only transaction
現在,它成為了新的備節點。
這樣,我們就實現了linux下的主備節點的切換。