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連接到主數據庫所需要的連接串。

   7. 啟動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)

   可以看到數據已經同步到了備庫,基本上感覺不到延遲。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM