1. 程式人生 > >postgresql9.6主從高可用原始碼環境編譯配置詳解

postgresql9.6主從高可用原始碼環境編譯配置詳解

系統版本:centos7

8核

32G記憶體

主從伺服器IP:

192.168.125.33 postgreSQL master

192.168.125.34 postgreSQL slave

1、建立資料庫管理賬戶

# groupadd pggroup

# useradd -g pggroup pguser 

# passwd pguser

2、安裝依賴包

yum install readline-devel zlib-devel -y

如果不安裝以上兩個包,編譯postgresql就會報缺少相應包的錯誤,導致無法通過。

yum install postgresql-contrib

http://mirror.centos.org/centos/7/os/x86_64/Packages/uuid-devel-1.6.2-26.el7.x86_64.rpm

版本和系統的uuid版本一樣,uuid-1.6.2-26.el7.x86_64

rpm -ivh uuid-devel-1.6.2-26.el7.x86_64.rpm

如果不安裝以上的一個包,編譯postgresql就會報以下的錯誤:

configure: error: library 'ossp-uuid' or 'uuid' is required for OSSP-UUID"

如果源裡邊有這個包,可以使用yum進行安裝。

3、編譯

主從伺服器上傳包postgresql-9.6.3.tar.gz,並進行編譯

# tar -zxf postgresql-9.6.3.tar.gz

# cd postgresql-9.6.3

# ./configure --prefix=/usr/local/postgresql --with-ossp-uuid

# make && make install

4、編譯uuid模組和pg_stat_statements模組

如果環境中不需要使用UUID型別的函式,也不需要pg_stat_statements函式模組對分析sql對資源佔用的情況的話,可以跳過UUID和

pg_stat_statements的處理,當然在之後的配置檔案也要相應做修改。

# cd contrib/uuid-ossp

# make && make install 

上邊如果不編譯uuid-ossp,就會出現下面的錯誤:

postgres=# create extension "uuid-ossp";

ERROR:  could not open extension control file "/usr/local/postgresql/share/extension/uuid-ossp.control": No such file or directory

# cd contrib/pg_stat_statements

# make && make install

5、配置環境變數

# vi /etc/profile

export PGHOME=/usr/local/postgresql

export PGDATA=/data/pg_data

export PATH=$PATH:$PGHOME/bin

# source /etc/profile

6、給目錄賦予許可權

# make /data/pg_data

# chown -R pguser:pggroup /data/pg_data

# chown -R pguser:pggroup /usr/local/postgresql

7、主伺服器初始化資料庫

首先切換到普通使用者

# su pguser

$ initdb -D /data/pg_data

啟動服務

$ pg_ctl -D /data/pg_data start

8、建立資料同步使用者

$ psql -h 127.0.0.1 -d postgres

postgres=# create role repuser login replication encrypted password '密碼自己定義';

修改管理賬戶登入密碼

postgres=# ALTER USER pguser WITH PASSWORD '密碼自己定義'

postgres=# \q

9、修改配置檔案

編輯pg_hba.conf

bash-4.2$ vi /data/pg_data/pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only

local   all             all                                     md5

# IPv4 local connections:

host    all             all             127.0.0.1/32            md5

host    all             all             192.168.125.0/24            md5

host    all             all             192.168.99.0/24            md5

# replication privilege.

host    replication     repuser         192.168.125.0/24             md5

說明:

TYPE定義了多種連線PostgreSQL的方式,分別是:“local”使用本地unix套接字,“host”使用TCP/IP連線(包括SSL和非SSL),“host”結合“IPv4地址”使用IPv4方式,結合“IPv6地址”則使用IPv6方式,“hostssl”只能使用SSL TCP/IP連線,“hostnossl”不能使用SSL TCP/IP連線。

DATABASE指定哪個資料庫,多個數據庫,庫名間以逗號分隔。“all”只有在沒有其他的符合條目時才代表“所有”,如果有其他的符合條目則代表“除了該條之外的”,因為“all”的優先順序最低。

USER指定哪個資料庫使用者(PostgreSQL正規的叫法是角色,role)。多個使用者以逗號分隔。

ADDRESS項local方式不必填寫,該項可以是IPv4地址或IPv6地址,可以定義某臺主機或某個網段。

配置 192.168.125.X  和 192.168.99.X 兩個網段的伺服器可以訪問資料庫

METHOD指定如何處理客戶端的認證。常用的有ident,md5,password,trust,reject。

ident是Linux下PostgreSQL預設的local認證方式,凡是能正確登入伺服器的作業系統使用者(注:不是資料庫使用者)就能使用本使用者對映的資料庫使用者不需密碼登入資料庫。

md5是常用的密碼認證方式,如果你不使用ident,最好使用md5。密碼是以md5形式傳送給資料庫,較安全,且不需建立同名的作業系統使用者。

password是以明文密碼傳送給資料庫,建議不要在生產環境中使用。

trust是隻要知道資料庫使用者名稱就不需要密碼或ident就能登入,建議不要在生產環境中使用。

reject是拒絕認證。

最後一行配置的是從庫伺服器的資訊,也就是同步主庫資料資料庫的資訊。

編輯postgresql.conf

bash-4.2$ vi /data/pg_data/postgresql.conf

新增下面配置,配置檔案有下面配置的要刪除(包括前邊有警號'#'的)

listen_addresses = '*'

wal_level = hot_standby

max_wal_senders= 6

wal_keep_segments = 10240

max_connections = 512

archive_mode = on

archive_command = 'cp %p /data/pg_data/pg_archive/%f'

# 配置pg_stat_statements

shared_preload_libraries = 'pg_stat_statements'  

track_io_timing = on

track_activity_query_size = 2048

pg_stat_statements.max = 10000

pg_stat_statements.track = all

pg_stat_statements.track_utility = off

pg_stat_statements.save = on

建立歸檔檔案存放目錄

bash-4.2$ mkdir /data/pg_data/pg_archive

#如果需要的話需要調整做效能的優化

shared_buffers = 3276MB

work_mem = 655MB

effective_cache_size = 2GB

maintence_work_mem = 256MB

max_connections = 4000

# vi /etc/sysctl.conf

kernel.sem = 50100 128256000 50100 2560

# sysctl -p

重啟服務

$ pg_ctl -D /data/pg_data restart

10、建立uuid和pg_stat_statements

登入相應的資料庫

postgres=# create extension "uuid-ossp";

CREATE EXTENSION

驗證

postgres=# select uuid_generate_v4();

           uuid_generate_v4           

--------------------------------------

 28cbfa1e-d659-4aa2-a0fd-95fc7ec0aa8b

(1 row)

postgres=# create extension pg_stat_statements;

驗證

select * from pg_stat_statements order by total_time desc limit 5;

11、建立資料庫、訪問使用者並給資料庫賦權

主伺服器

postgres=# create user testuser with password '密碼自定義';

CREATE ROLE

postgres=# create database test owner yourpassword;

CREATE DATABASE

postgres=# grant all privileges on database test to testuser;

GRANT

登入資料庫

psql -U testuser -d test -W

12、同步資料

從伺服器,在普通使用者下

bash-4.2$ pg_basebackup -h 192.168.125.33 -U repuser -D /data/pg_data -X stream -P

Password:

36413/36413 kB (100%), 1/1 tablespace

13、從伺服器修改配置檔案recovery.conf、postgresql.conf

bash-4.2$ cp /usr/local/postgresql/share/pgsql/recovery.conf.sample /data/pg_data/recovery.conf

bash-4.2$ vi /data/pg_data/recovery.conf

新增下面配置,配置檔案有下面配置的要刪除(包括前邊有警號'#'的)

standby_mode = on

primary_conninfo = 'host=192.168.125.33 port=5432 user=repuser password=yourpassword keepalives_idle=60'

recovery_target_timeline = 'latest'

bash-4.2$ vi /data/pg_data/postgresql.conf

新增下面配置

hot_standby = on

max_standby_streaming_delay = 30s

wal_receiver_status_interval = 10s

hot_standby_feedback = on

postgresql.conf配置檔案說明:

# 使PostgreSQL可以接受來自任意IP的連線請求

listen_addresses = '*'

# postgres在9.0之後引入了主從的流複製機制,所謂流複製,就是從庫通過tcp流從主庫中同步相應的資料。

# 設定主為wal的主機

wal_level = hot_standby

# 設定可以最多有幾個流複製連線,有幾個從,就設定幾個

max_wal_senders= 6

# postgresql的pg_xlog是記錄資料庫事務資訊用的,叫wal日誌(write ahead log),就是在寫資料到磁盤裡成為固定資料之前,先寫入到日誌裡,然後一定條件下觸發呼叫fsync()將此資料刷到磁碟。

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

wal_keep_segments = 10240

# 最大伺服器連線數

max_connections = 4000

# 啟用archive_mode

# 當啟用archive_mode時,通過設定archive_command將已完成的WAL段傳送到歸檔儲存。除了off,disable,還有兩種模式:on,always。在正常操作期間,兩種模式之間沒有區別,但是當設定為always的情況下,WAL archiver在存檔恢復或待機模式下也被啟用。在always模式下,從歸檔還原或流式複製流的所有檔案都將被歸檔(再次)。archive_mode和archive_command是單獨的變數,因此可以在不更改存檔模式的情況下更改archive_command。此引數只能在伺服器啟動時設定。當wal_level設定為minimal時,無法啟用archive_mode。

archive_mode = on

# 把歸檔檔案儲存到 /data/pg_data/pg_archive 目錄下

archive_command = 'cp %p /data/pg_data/pg_archive/%f'

# 設定資料庫伺服器既用於資料歸檔,也用於資料查詢。

hot_standby = on

# 資料流備份的最大延遲時間

max_standby_streaming_delay = 30s

# 多久向主報告一次從的狀態,當然從每次資料複製都會向主報告狀態,這裡只是設定最長的間隔時間。

wal_receiver_status_interval = 10s

# 如果有錯誤的資料複製,是否向主進行反饋

hot_standby_feedback = on

# 在啟動時匯入pg_stat_statements 動態庫

shared_preload_libraries = 'pg_stat_statements' 

# 如果要跟蹤IO消耗的時間,還需要開啟如下引數

track_io_timing = on

# 設定單條SQL的最長長度,超過被截斷顯示

track_activity_query_size = 2048

# 監控的語句最多為10000句

pg_stat_statements.max = 10000

# pg_stat_statements.track控制哪些語句會被該模組計數。指定top可以跟蹤頂層語句(那些直接由客戶端發出的語句),指定all還可以跟蹤巢狀的語句(例如在函式中呼叫的語句),指定none可以禁用語句統計資訊收集。預設值是top。 只有超級使用者能夠改變這個設定。

pg_stat_statements.track = all

# 配置pg_stat_statements.track_utility控制該模組不跟蹤工具命令。工具命令是除了SELECT、INSERT、 UPDATE和DELETE之外所有的其他命令。預設值是on。 只有超級使用者能夠改變這個設定。

pg_stat_statements.track_utility = off

# 指定在伺服器關閉之後還儲存語句統計資訊。如果被設定為off,那麼關閉後不儲存統計資訊並且在伺服器啟動時也不會重新載入統計資訊。預設值為on。這個引數只能在postgresql.conf檔案中或者在伺服器命令列上設定。

pg_stat_statements.save = on

# 設定資料庫伺服器將使用的共享記憶體緩衝區量

shared_buffers = 3276MB

#  work_mem在pgsql 8.0之前叫做sort_mem。postgresql在執行排序操作時,會根據work_mem的大小決定是否將一個大的結果集拆分為幾個小的和 work_mem查不多大小的臨時檔案。顯然拆分的結果是降低了排序的速度。因此增加work_mem有助於提高排序的速度。通常設定為實際RAM的2% -4%,根據需要排序結果集的大小而定。

work_mem = 655MB

# postgresql能夠使用的最大快取

effective_cache_size = 2GB

# 這裡定義的記憶體只是在CREATE INDEX, VACUUM等時用到,因此用到的頻率不高,但是往往這些指令消耗比較多的資源,因此應該儘快讓這些指令快速執行完畢。

maintence_work_mem = 256MB

# vi /etc/sysctl.conf

kernel.sem = 50100 128256000 50100 2560

# sysctl -p

14、從伺服器啟動服務

首先修改目錄許可權

# chmod 700 /data/pg_data

# su pguser

bash-4.2$ pg_ctl -D /data/pg_data start

15、驗證

主伺服器:

bash-4.2$ psql -h 127.0.0.1 -d postgres

檢視同步資料庫

postgres=# select client_addr,sync_state from pg_stat_replication;

 client_addr  | sync_state

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

 192.168.125.34 | async

 postgres=# create database test1;

CREATE DATABASE

檢視資料庫

postgres=# \l

從伺服器:

# su pguser

bash-4.2$ psql -h 127.0.0.1 -d postgres

檢視 test1庫是否已經同步過來

postgres=# \l

 

16、主從高可用元件安裝配置

16.1、主從伺服器安裝keepalived

# yum install -y keepalived

16.2、主伺服器配置

# cd /etc/keepalived

# vi keepalived.conf

! Configuration File for keepalived

global_defs {

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id pg

}

vrrp_script chk_pg {

    script "/etc/keepalived/scripts/pgsql_check.sh"

    interval 2

    weight -5

    fall 2

    rise 1

}

vrrp_instance VI_1 {

    state BACKUP

    interface eth0

    virtual_router_id 61

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    track_script {

        chk_pgsql

    }

    virtual_ipaddress {

        192.168.125.200

    }

}

# mkdir log 

# mkdir scripts 

# vi scripts/pgsql_check.sh 

#!/bin/bash

A=`ps -C postgres --no-header | wc -l`

# 判斷vip浮到哪裡

B=`ip a | grep 192.168.125.200 | wc -l`

# 判斷是否是從庫處於等待的狀態

C=`ps -ef | grep postgres | grep 'startup process' | wc -l`

# 判斷從庫連結主庫是否正常

D=`ps -ef | grep postgres | grep 'receiver' | wc -l`

# 判斷主庫連線從庫是否正常

E=`ps -ef | grep postgres | grep 'sender' | wc -l`

# 如果pg死了,將訊息寫入日記並且關閉keepalived

if [ $A -eq 0 ];then

    echo "`date "+%Y-%m-%d--%H:%M:%S"` postgresql stop so vip stop " >> /etc/keepalived/log/check_pg.log

    systemctl stop keepalived

else

# 判斷出主掛了,vip浮到了從,提升從的地位讓他可讀寫

        if [ $B -eq 1 -a $C -eq 1 -a $D -eq 0 ];then

                su - pguser -c "pg_ctl promote -D /data/pg_data"

                echo "`date "+%Y-%m-%d--%H:%M:%S"` standby promote " >> /etc/keepalived/log/check_pg.log

        fi

# 判斷出自己是主並且和從失去聯絡

        if [ $B -eq 1 -a $C -eq 0 -a $D -eq 0 -a $E -eq 0 ];then

                                sleep 10

                echo "`date "+%Y-%m-%d--%H:%M:%S"` can't find standby " >> /etc/keepalived/log/check_pg.log

        fi

fi

16.3、從伺服器配置

# cd /etc/keepalived

# vi keepalived.conf

! Configuration File for keepalived

global_defs {

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id pg

}

vrrp_script chk_pg {

    script "/etc/keepalived/scripts/pgsql_check.sh"

    interval 2

    weight -5

    fall 2

    rise 1

}

vrrp_instance VI_1 {

    state BACKUP

    interface eth0

    virtual_router_id 61

    priority 96

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    track_script {

        chk_pgsql

    }

    virtual_ipaddress {

        192.168.125.200

    }

}

# mkdir log 

# mkdir scripts 

# vi scripts/pgsql_check.sh 

#!/bin/bash

A=`ps -C postgres --no-header | wc -l`

# 判斷vip浮到哪裡

B=`ip a | grep 192.168.125.200 | wc -l`

# 判斷是否是從庫處於等待的狀態

C=`ps -ef | grep postgres | grep 'startup process' | wc -l`

# 判斷從庫連結主庫是否正常

D=`ps -ef | grep postgres | grep 'receiver' | wc -l`

# 判斷主庫連線從庫是否正常

E=`ps -ef | grep postgres | grep 'sender' | wc -l`

# 如果pg死了,將訊息寫入日記並且關閉keepalived

if [ $A -eq 0 ];then

    echo "`date "+%Y-%m-%d--%H:%M:%S"` postgresql stop so vip stop " >> /etc/keepalived/log/check_pg.log

    systemctl stop keepalived

else

# 判斷出主掛了,vip浮到了從,提升從的地位讓他可讀寫

        if [ $B -eq 1 -a $C -eq 1 -a $D -eq 0 ];then

                su - pguser -c "pg_ctl promote -D /data/pg_data"

                echo "`date "+%Y-%m-%d--%H:%M:%S"` standby promote " >> /etc/keepalived/log/check_pg.log

        fi

# 判斷出自己是主並且和從失去聯絡

        if [ $B -eq 1 -a $C -eq 0 -a $D -eq 0 -a $E -eq 0 ];then

                                sleep 10

                echo "`date "+%Y-%m-%d--%H:%M:%S"` can't find standby " >> /etc/keepalived/log/check_pg.log

        fi

fi

16.4、主從伺服器啟動服務

# systemctl start keepalived.service

17、訪問資料庫就可以通過訪問虛擬IP192.168.125.200直接訪問


18、主從切換

當主庫資料庫伺服器宕機或者資料庫服務異常停止後,從庫會自動切換為主庫,且虛擬IP會在從庫上生成,實現從庫自動切換為主庫,但是停止的原來主庫要變為現在的從庫需要手動切換。

原來的主作為現在的備

首先做備份

# cp pg_data pg_data.bak -Rp

刪除檔案

$ cd pg_data

$ rm -rf *

同步資料

$ pg_basebackup -h 192.168.125.34 -U repuser -D /data/pg_data -X stream -P

$ mv recovery.done recovery.conf

$ vi recovery.conf

primary_conninfo = 'host=192.168.125.33 port=5432 user=repuser password=yourpassword keepalives_idle=60'

>>

primary_conninfo = 'host=192.168.125.34 port=5432 user=repuser password=yourpassword keepalives_idle=60'

啟動主機keepalived

# systemctl start keepalived.service