1. 程式人生 > >PostgreSQL Hot-Standby

PostgreSQL Hot-Standby

一、簡介

PostgreSQL資料庫提供了類似Oracle的standby資料庫的功能。PostgreSQL9.0 standby資料庫在應用WAL日誌的同時,也可以提供只讀服務,這是PostgreSQL9.0中最激動人心的功能,這個功能在oracle資料庫中也只是最新版本11g中才有的新功能。這個功能在oracle中叫active dataguard,在PostgreSQL中稱為hot standby。在利用日誌恢復資料的同時可以用只讀的方式開啟資料庫,使用者可以在備用資料庫上進行查詢、報表等操作,也可用做讀寫分離。在PostgreSQL9.0之前,也可以搭建standby資料庫,但standby資料庫只能處於恢復狀態中,不能開啟,也不支援只讀開啟。而這種情況在9.0之後徹底改變了。

PostgreSQL 9.0中日誌傳送的方法有兩種:

基於檔案(base-file)的傳送方式,這種方式是PostgreSQL9.0之前就提供的方法。也就是伺服器寫完一個WAL日誌檔案後,才把WAL日誌檔案拷貝到standby資料庫上去應用。

流複製(streaming replication)的方法,這是PostgreSQL9.0才提供的新方法。這個方法就是事務提交後,就會把生成的日誌非同步的傳送到standby資料庫上應用,這比基本檔案的日誌傳送方法有更低的資料延遲。

二、設定步驟

基於檔案(base-file)的傳送方式在PostgreSQL8.X中就有的方式,這裡不就介紹了,這裡主要介紹流複製的standby的搭建方法,設定步驟如下:

對主資料庫做一個基礎備份,然後把基礎備份拷貝到standby機器,把基礎備份恢復到standby機器上。

1、在主庫上設定wal_level = hot_standby。

2、在主資料庫上設定wal_keep_segments為一個足夠大的值,以防止主庫生成WAL日誌太快,日誌還沒有來得及傳送到standby,就會迴圈覆蓋了;

3、在主資料庫上設定max_wal_sender引數,這個引數是控制主庫可以最多有多少個併發的standby資料庫;

4、在主資料庫上建一個超級使用者,standby資料庫會使用這個使用者連線到主庫上拖WAL日誌。

5、在主資料庫上的pg_hba.conf中設定listen_addresses和連線驗證選項,允許standby資料庫連線到主庫上來拖WAL日誌資料,如下所示:

# TYPE DATABASE USER CIDR-ADDRESS METHOD

host replication postgres 10.0.0.136/8 md5
其中資料庫名必須填“replication”, 這是一個為standby連線使用了一個虛擬的資料庫名稱。使用者postgres就是步驟4上給standby連線使用的在主庫上建的一個超級使用者。10.0.0.136就是standby資料庫的IP地址。

6、在備份上建一個recovery.conf,設定以下幾項:

standby_mode = 'on'

primary_conninfo = 'host=127.0.0.1 port=5432 user=postgres password=123456'

trigger_file = '/opt/pgstb/trigger_standby'
standby_mode設定為'on',表明資料庫恢復完成後,不會被斷開,仍然處理等待日誌的模式。

primary_conninfo上standby連線到主資料庫所需要的連線串。

  1. 啟動standby資料庫,這樣standby資料庫就算搭建好了。

三、系統環境

系統平臺:Suse 11.4

PostgreSQL版本:9.0.3

四、例項分析

主資料庫:

Standby資料庫:

主資料庫的資料目錄為:/var/lib/pgsql/data,standby資料庫的資料目錄為/var/lib/pgsql/data。

在主資料庫的/var/lib/pgsql/data/postgresql.conf檔案中設定如下配置項:

wal_level = hot_standby

max_wal_senders = 2

wal_keep_segments = 32
在主資料庫中的/var/lib/pgsql/data/pg_hba.conf中新增如下配置:

host replication postgres 10.0.0.136/8 md5
在資料庫中建一個postgres使用者用於給standby連線主庫使用:

psql -d postgres

postgres=# create user postgres superuser password '123456';

CREATE ROLE
重新啟動主資料庫,讓配置生效:

對主資料庫做一個基礎備份:

先用select pg_start_backup();命令把資料庫切換到備份狀態。

把主資料庫目錄拷貝到備庫目錄就可以了:

檢視standby備庫目錄:

拷貝完成後,結束主庫的備份狀態:

修改備庫的配置檔案/var/lib/pgsql/data/postgresql.conf檔案中的相關項為如下內容:

hot_standby = on
把其中的hot_standby設定為on。

拷貝示例檔案/usr/share/postgresql/recovery.conf.sample到/var/lib/pgsql/data目錄下,然後改名成recovery.conf,修改相關的配置項為如下內容:

刪除原先從主庫上過來的/var/lib/pgsql/data/postmaster.pid檔案,然後啟動備庫:

複製程式碼
linux-david:/var/lib/pgsql/data # rm postmaster.pid

linux-david:/var/lib/pgsql/data # export PGDATA=/var/lib/pgsql/data

linux-david:/var/lib/pgsql/data # echo $PGDATA

/var/lib/pgsql/data

linux-david:/var/lib/pgsql/data # service postgresql start

server starting

linux-david:/var/lib/pgsql/data # LOG: database system was interrupted; last known up at 2010-08-21 22:43:04 CST

LOG: entering standby mode

LOG: redo starts at 0/1000020

LOG: record with zero length at 0/10000B0

LOG: streaming replication successfully connected to primary

LOG: consistent recovery state reached at 0/2000000

LOG: database system is ready to accept read only connections
複製程式碼
這時可以看到備庫已經可以接受只讀連線了。

在主庫上做一些操作:

複製程式碼
linux-david:/var/lib/pgsql/data # psql -p 5432 -d postgres

psql (9.0beta4)

Type "help" for help.

postgres=# create table t (id int primary key,name varchar(20));

NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pkey" for table "t"

CREATE TABLE

postgres=# insert into t values (1,'xxxxxxx');

INSERT 0 1

postgres=# insert into t values (2,'xxxxxxx');

INSERT 0 1

postgres=#
複製程式碼

然後在備庫上看是否同步到了備庫:

複製程式碼
linux-david:/var/lib/pgsql/data # psql -p 5432 -d postgres

psql (9.0beta4)

Type "help" for help.

postgres=# \d

      List of relations

Schema | Name | Type | Owner

--------+------+-------+-------

public | t | table | osdba

(1 row)

postgres=# select * from t;

id | name

----+---------

1 | xxxxxxx

2 | xxxxxxx

(2 rows)
複製程式碼
可以看到資料已經同步到了備庫,基本上感覺不到延遲。