天天看點

pgpool 主從流複制模式下的安裝使用

pgpool-ii 是一個位于 postgresql 伺服器和 postgresql 資料庫用戶端之間的中間件,它提供以下功能: 

 連接配接池 

pgpool-ii 保持已經連接配接到 postgresql 伺服器的連接配接,并在使用相同參數(例如:使用者名,資料庫,協定版本)連接配接進來時重用它們。它減少了連接配接開銷,并增加了系統的總體吞吐量。 

 複制 

pgpool-ii 可以管理多個 postgresql 伺服器。激活複制功能并使在2台或者更多 postgresql 節點中建立一個實時備份成為可能,這樣,如果其中一台節點失效,服務可以不被中斷繼續運作。 

 負載均衡 

如果資料庫進行了複制,則在任何一台伺服器中執行一個 select 查詢将傳回相同的結果。pgpool-ii 利用了複制的功能以降低每台 postgresql 伺服器的負載。它通過分發 select 查詢到所有可用的伺服器中,增強了系統的整體吞吐量。在理想的情況下,讀性能應該和 postgresql 伺服器的數量成正比。負載均衡功能在有大量使用者同時執行很多隻讀查詢的場景中工作的效果最好。 

 并行查詢 

使用并行查詢時,資料可以被分割到多台伺服器上,是以一個查詢可以在多台伺服器上同時執行,以減少總體執行時間。并行查詢在查詢大規模資料的時候非常有效。 

現有的資料庫應用程式基本上可以不需要修改就可以使用 pgpool-ii 

現有環境: 

主:pgtest01    192.168.12.251  pg9.4.5 

從:pgtest02    192.168.12.252  pg9.4.5 

安裝目錄 /pgtina 

資料目錄 /pgtina/data 

=================安裝pgpool=========== 

1、下載下傳安裝包: 

http://www.pgpool.net/mediawiki/index.php/downloads  

[root@pgtest01 package]# wget http://192.168.10.100/pgpool-ii-3.4.3.tar.gz 

2、解壓安裝 

[root@pgtest01 package]# tar -zxvf pgpool-ii-3.4.3.tar.gz 

[root@pgtest02 /]# mkdir pgpool 

[postgres@pgtest01 pgtina]$ cat ~/.bash_profile 

export ld_library_path=/pgtina/lib 

export path=/pgtina/bin:$path 

[root@pgtest02 pgpool-ii-3.4.3]# pwd 

/package/pgpool-ii-3.4.3 

[root@pgtest01 pgpool-ii-3.4.3]# ./configure --prefix=/pgpool  -with-pgsql=path -with-pgsql=/pgtina  --with-openssl  預設情況下,pgpool-ii将安裝到 /usr/local 目錄。 

--編譯報錯: 

checking openssl/ssl.h usability... no 

checking openssl/ssl.h presence... no 

checking for openssl/ssl.h... no 

configure: error: header file <openssl/ssl.h> is required for ssl 

[root@pgtest01 pgpool-ii-3.4.3]# yum install openssl 

[root@pgtest01 pgpool-ii-3.4.3]# yum install openssl-devel   可以寫成yum install -y  openssl openssl-devel 

編譯通過,進行安裝 

make 

make install 

3、安裝pg_regclass 和pg_recovery(兩節點操作) 

如果你在使用 postgresql 8.0 或之後的版本,強烈推薦在需要通路的 postgresql 中安裝 pgpool_regclass 函數, 

因為它被 pgpool-ii 内部使用。 如果不這樣做,在不同的 schema 中處理相同的表名會出現問題(臨時表不會出問題)。 

[root@pgtest01 extension]# find / -name "pgpool*.sql" 

/package/pgpool-ii-3.4.3/src/sql/pgpool_adm/pgpool_adm--1.0.sql 

/package/pgpool-ii-3.4.3/src/sql/pgpool-recovery/pgpool_recovery--1.1.sql 

/package/pgpool-ii-3.4.3/src/sql/pgpool-regclass/pgpool_regclass--1.0.sql 

[root@pgtest01 extension]# find / -name "pgpool*.control" 

/package/pgpool-ii-3.4.3/src/sql/pgpool_adm/pgpool_adm.control 

/package/pgpool-ii-3.4.3/src/sql/pgpool-recovery/pgpool_recovery.control 

/package/pgpool-ii-3.4.3/src/sql/pgpool-regclass/pgpool_regclass.control 

template1=# create extension pgpool_regclass; 

error:  could not open extension control file "/pgtina/share/postgresql/extension/pgpool_regclass.control": no such file or directory 

檢視手冊 

http://www.pgpool.net/docs/latest/pgpool-zh_cn.html 

正确的方式: 

cd pgpool-ii-x.x.x/sql/pgpool-regclass 

在這之後: 

psql -f pgpool-regclass.sql template1 

或者 

psql template1 

create extension pgpool_regclass; 

[postgres@pgtest01 ~]$ psql -f /pgtina/share/postgresql/extension/pgpool_regclass--1.0.sql  template1 

use "create extension pgpool_regclass" to load this file. 

[root@pgtest01 pgpool-regclass]# cd /package/pgpool-ii-3.4.3/src/sql 

[root@pgtest01 sql]# ll 

total 24 

-rw-rw-r--. 1 postgres postgres  617 jul 24 13:47 insert_lock.sql 

-rw-rw-r--. 1 postgres postgres 1407 jul 24 13:47 makefile 

drwxrwsr-x. 2 postgres postgres 4096 jul 24 13:47 pgpool_adm 

drwxrwsr-x. 2 postgres postgres 4096 jul 24 13:47 pgpool-recovery 

drwxrwsr-x. 2 postgres postgres 4096 jul 24 13:47 pgpool-regclass 

-rw-rw-r--. 1 postgres postgres  834 jul 24 13:47 system_db.sql 

[root@pgtest01 sql]# make 

make: pg_config: command not found 

make: *** no targets.  stop. 

[root@pgtest01 sql]# source /home/postgres/.bash_profile 

[root@pgtest01 sql]# make install 

[root@pgtest01 sql]# cd /pgtina/share/postgresql/extension/    --果然有了這些檔案 

[root@pgtest01 extension]# ll 

total 44 

-rw-r--r--. 1 root     root     2664 nov 19 14:09 pgpool_adm--1.0.sql 

-rw-r--r--. 1 root     root      146 nov 19 14:09 pgpool_adm.control 

-rw-r--r--. 1 root     root     1002 nov 19 14:09 pgpool_recovery--1.1.sql 

-rw-r--r--. 1 root     root      178 nov 19 14:09 pgpool_recovery.control 

-rw-r--r--. 1 root     root      557 nov 19 14:09 pgpool-recovery.sql 

-rw-r--r--. 1 root     root      283 nov 19 14:09 pgpool_regclass--1.0.sql 

-rw-r--r--. 1 root     root      152 nov 19 14:09 pgpool_regclass.control 

-rw-r--r--. 1 root     root      142 nov 19 14:09 pgpool-regclass.sql 

-rw-r--r--. 1 postgres postgres  332 nov 18 10:51 plpgsql--1.0.sql 

-rw-r--r--. 1 postgres postgres  179 nov 18 10:51 plpgsql.control 

-rw-r--r--. 1 postgres postgres  381 nov 18 10:51 plpgsql--unpackaged--1.0.sql 

--再來建立:---成功 

create extension 

template1=# create extension pgpool_recovery; 

template1=# \df 

                                                              list of functions 

schema |        name         | result data type |                               argument data types                                |  type  

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

public | pgpool_pgctl        | boolean          | action text, stop_mode text                                                      | normal 

public | pgpool_recovery     | boolean          | script_name text, remote_host text, remote_data_directory text                   | normal 

public | pgpool_recovery     | boolean          | script_name text, remote_host text, remote_data_directory text, remote_port text | normal 

public | pgpool_remote_start | boolean          | remote_host text, remote_data_directory text                                     | normal 

public | pgpool_switch_xlog  | text             | arcive_dir text                                                                  | normal 

(5 rows) 

備注: 每個庫都需要安裝 pgpool_regclass,為了友善在 template1 上安裝 pgpool_regclass,以後建立的庫都以 template1 為模闆庫。 

5.配置 pgpool-ii ( 兩節點操作) 

[root@pgtest02 sql]# cd /pgpool/etc/ 

[root@pgtest02 etc]# cp pcp.conf.sample pcp.conf 

[root@pgtest01 etc]# find / -name "pg_md5" 

/package/pgpool-ii-3.4.3/src/tools/pgmd5/pg_md5 

/pgpool/bin/pg_md5 

[root@pgtest01 etc]# /pgpool/bin/pg_md5 -u postgres -p 

password: test12 

60474c9c10d7142b7508ce7a50acf414 

備注: pgpool提供pcp接口,可以檢視,管理pgpool的狀态,并且可以遠端操作pgpool,pcp.conf用來對pcp相關指令認證的檔案,格式為userid:md5passwd。 

--編寫 pcp.conf 檔案,寫入以下 

# userid:md5passwd 

postgres:60474c9c10d7142b7508ce7a50acf414 

pgpool:ba777e4c2f15c11ea8ac3be7e0440aa0 

vi /etc/hosts 

192.168.12.251 pgtest01 

192.168.12.252 pgtest02 

--配置 ifconfig, arping 執行權限 

[root@pgtest02 etc]# chmod u+s /sbin/ifconfig 

[root@pgtest02 etc]# chmod u+s /usr/sbin 

備注:  以理普通使用者能夠執行以上指令,  failover_command 指令要用到。 

--配置兩節點信任關系 

[root@pgtest01 etc]# su - postgres 

[postgres@pgtest01 ~]$ ssh postgres@pgtest02   --配置後要求無密碼登入 

[postgres@pgtest01 ~]$ ssh-keygen 

enter file in which to save the key (/home/postgres/.ssh/id_rsa): 

[postgres@pgtest01 ~]$ ssh-copy-id postgres@pgtest02 

postgres@pgtest02's password: 

now try logging into the machine, with "ssh 'postgres@pgtest02'", and check in: 

  .ssh/authorized_keys 

to make sure we haven't added extra keys that you weren't expecting. 

[postgres@pgtest01 ~]$ ssh postgres@pgtest02   --成功 

在另一台機器上也操作一下 

--配置 pgpool.conf 

[root@pgtest01 etc]# cd /pgpool/etc 

[root@pgtest01 etc]# cp pgpool.conf.sample pgpool.conf 

--開啟日志 

    在日志 /etc/rsyslog.conf  加入以下行 

# pgpool 

local0.*    /var/log/pgpool.log    

[root@pgtest01 etc]# vi /etc/rsyslog.conf 

[root@pgtest01 etc]# /etc/init.d/rsyslog  restart 

shutting down system logger:                               [  ok  ] 

starting system logger:                                    [  ok  ] 

--主節點的 pgpool.conf 

[postgres@pgtest01 etc]$ grep ^[a-z] pgpool.conf 

listen_addresses = '*' 

port = 9999 

socket_dir = '/tmp' 

pcp_port = 9898 

pcp_socket_dir = '/tmp' 

backend_hostname0 = '192.168.12.251'   ##配置資料節點 db1 

backend_port0 = 5432 

backend_weight0 = 1 

backend_flag0 = 'allow_to_failover' 

backend_hostname1 = '192.168.12.252'   ##配置資料節點  db2 

backend_port1 = 5432 

backend_weight1 = 1 

backend_flag1 = 'allow_to_failover' 

enable_pool_hba = on 

pool_passwd = 'pool_passwd' 

authentication_timeout = 60 

ssl = off 

num_init_children = 32 

max_pool = 4 

child_life_time = 300 

child_max_connections = 0 

connection_life_time = 0 

client_idle_limit = 0 

log_destination = 'syslog' 

print_timestamp = on 

log_connections = on 

log_hostname = on 

log_statement = on 

log_per_node_statement = off 

log_standby_delay = 'none' 

syslog_facility = 'local0' 

syslog_ident = 'pgpool' 

debug_level = 0 

pid_file_name = '/pgpool.pid' 

logdir = '/pgpool/log' 

connection_cache = on 

reset_query_list = 'abort; discard all' 

replication_mode = off 

replicate_select = off 

insert_lock = on 

lobj_lock_table = '' 

replication_stop_on_mismatch = off 

failover_if_affected_tuples_mismatch = off 

load_balance_mode = on 

ignore_leading_white_space = on 

white_function_list = '' 

black_function_list = 'nextval,setval' 

master_slave_mode = on                     # 設定流複制模式 

master_slave_sub_mode = 'stream'   # 設定流複制模式 

sr_check_period = 5 

sr_check_user = 'repluser' 

sr_check_password = 'repluser' 

delay_threshold = 16000 

follow_master_command = '' 

---從這開始沒有了 

parallel_mode = off                 

pgpool2_hostname = '' 

system_db_hostname  = 'localhost' 

system_db_port = 5432 

system_db_dbname = 'pgpool' 

system_db_schema = 'pgpool_catalog' 

system_db_user = 'pgpool' 

system_db_password = '' 

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

health_check_period = 5 

health_check_timeout = 20 

health_check_user = 'repuser' 

health_check_password = 'rep123us345er' 

health_check_max_retries = 3 

health_check_retry_delay = 1 

failover_command = '/opt/pgpool/failover_stream.sh %h '  ## 配置 failover 腳本,腳本内容下面會貼出。 

failback_command = '' 

fail_over_on_backend_error = on 

search_primary_node_timeout = 10 

recovery_user = 'nobody' 

recovery_password = '' 

recovery_1st_stage_command = '' 

recovery_2nd_stage_command = '' 

recovery_timeout = 90 

client_idle_limit_in_recovery = 0 

use_watchdog = on             ---注意打開watchdog 

trusted_servers = '' 

ping_path = '/bin' 

wd_hostname = '192.168.12.251' 

wd_port = 9000 

wd_authkey = '' 

delegate_ip = '192.168.12.240'   ## 配置 pgpool 的 vip,避免 pgpool 的單點故障 

ifconfig_path = '/sbin'    ## 以下幾個網卡指令不需要修改。 

if_up_cmd = 'ifconfig eth0:0 inet $_ip_$ netmask 255.255.255.0' 

if_down_cmd = 'ifconfig eth0:0 down' 

arping_path = '/usr/sbin'           # arping command path 

arping_cmd = 'arping -u $_ip_$ -w 1' 

clear_memqcache_on_escalation = on 

wd_escalation_command = '' 

wd_lifecheck_method = 'heartbeat' 

wd_interval = 10 

wd_heartbeat_port = 9694 

wd_heartbeat_keepalive = 2 

wd_heartbeat_deadtime = 30 

heartbeat_destination0 = '192.168.12.252'   # 配置對端的 hostname 

heartbeat_destination_port0 = 9694 

heartbeat_device0 = 'eth0' 

wd_life_point = 3 

wd_lifecheck_query = 'select 1' 

wd_lifecheck_dbname = 'template1' 

wd_lifecheck_user = 'nobody' 

wd_lifecheck_password = '' 

other_pgpool_hostname0 = '192.168.12.252'   ## 配置對端的 pgpool 

other_pgpool_port0 = 9999              ---注意這裡 

other_wd_port0 = 9000 

relcache_expire = 0 

relcache_size = 256 

check_temp_table = on 

memory_cache_enabled = off 

memqcache_method = 'shmem' 

memqcache_memcached_host = 'localhost' 

memqcache_memcached_port = 11211 

memqcache_total_size = 67108864 

memqcache_max_num_cache = 1000000 

memqcache_expire = 0 

memqcache_auto_cache_invalidation = on 

memqcache_maxcache = 409600 

memqcache_cache_block_size = 1048576 

memqcache_oiddir = '/var/log/pgpool/oiddir' 

white_memqcache_table_list = '' 

black_memqcache_table_list = '' 

--備節點的 pgpool.conf 

[postgres@pgtest02 etc]$ grep ^[a-z] pgpool.conf 

backend_hostname0 = '192.168.12.251' 

backend_hostname1 = '192.168.12.252' 

pid_file_name = '/opt/pgpool/pgpool.pid' 

master_slave_mode = on 

master_slave_sub_mode = 'stream' 

sr_check_period = 0 

-----以下沒有--- 

parallel_mode = off 

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

health_check_period = 0 

health_check_user = 'nobody' 

health_check_password = '' 

health_check_max_retries = 0 

failover_command = '/opt/pgpool/failover_stream.sh %h ' 

use_watchdog = on 

wd_hostname = '192.168.12.252' 

delegate_ip = '192.168.12.240' 

ifconfig_path = '/sbin' 

heartbeat_destination0 = '192.168.12.251' 

other_pgpool_hostname0 = '192.168.12.251' 

other_pgpool_port0 = 9999 

--/opt/pgpool/failover_stream.sh 腳本内容 

[pg93@db1 etc]$ cat /opt/pgpool/failover_stream.sh 

#! /bin/sh 

# failover command for streaming replication. 

# arguments: $1: new master hostname. 

new_master=$1 

trigger_command="$pghome/bin/pg_ctl promote -d $pgdata" 

# prompte standby database. 

/usr/bin/ssh -t $new_master $trigger_command 

exit 0; 

備注: 我這裡定義的 failover 腳本和 pgpool 手冊上的腳本不同,這裡使用了 pg_ctl promote 的切換方式, 

一方面以檔案觸發的形式個人覺得不是很好。另一方面:當以 trigger file 形式實作 ha 時會遇到不能來回切 

換的問題。 

如果仔細看,可以看到這個切換腳本并不嚴謹,每當有節點離線時,它都會觸發一次,也就是說如果目前掉線的 

是備節點,它也會到對端主庫執行一次 failover_command 指令,不過沒關系,并不影響。 

--啟動 pgpool(兩邊都要啟動) 

[pg93@db2 etc]$ pgpool 

備注: 此時可以檢視 /var/log/pgpool.log  日志了,注意兩節點都啟動。 

啟動失敗: 

[postgres@pgtest01 bin]$ /pgpool/bin/pgpool 

2015-11-19 15:33:30: pid 24712: warning:  failed while loading hba configuration from file:"/pgpool/etc/pool_hba.conf" 

2015-11-19 15:33:30: pid 24712: detail:  fopen failed with error: "no such file or directory" 

cp /pgpool/etc/pool_hba.conf.sample   pool_hba.conf 

[postgres@pgtest01 etc]$ ps -ef|grep pgpool 

postgres 24713     1  0 15:33 ?        00:00:00 /pgpool/bin/pgpool 

postgres 24718 24713  0 15:33 ?        00:00:00 pgpool: watchdog  

postgres 24719 24713  0 15:33 ?        00:00:00 pgpool: heartbeat receiver 

postgres 24720 24713  0 15:33 ?        00:00:00 pgpool: heartbeat sender 

postgres 24721 24713  0 15:33 ?        00:00:00 pgpool: lifecheck 

postgres 24781 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24782 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24783 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24784 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24785 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24786 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24787 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24788 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24789 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24790 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24791 24713  0 15:33 ?        00:00:00 pgpool: wait for connection request 

postgres 24792 24713  0 15:33 ?        00:00:00 pgpool: pcp: wait for connection request 

postgres 24794 24713  0 15:33 ?        00:00:00 pgpool: worker process 

postgres 24939 24680  0 15:38 pts/2    00:00:00 grep pgpool 

檢視背景日志: 

[root@pgtest01 log]# tail -f /var/log/pgpool.log 

nov 19 15:33:38 pgtest01 pgpool[24713]: [96-1] 2015-11-19 15:33:38: pid 24713: log:  child process with pid: 24751 exits with status 0 

nov 19 15:33:38 pgtest01 pgpool[24713]: [97-1] 2015-11-19 15:33:38: pid 24713: log:  child process with pid: 24751 exited with success and will not be restarted 

nov 19 15:33:38 pgtest01 pgpool[24713]: [98-1] 2015-11-19 15:33:38: pid 24713: log:  child process with pid: 24752 exits with status 0 

當從庫啟動後log更新了下面兩條: 

nov 19 15:40:34 pgtest01 pgpool[24718]: [10-1] 2015-11-19 15:40:34: pid 24718: log:  sending watchdog response 

nov 19 15:40:34 pgtest01 pgpool[24718]: [10-2] 2015-11-19 15:40:34: pid 24718: detail:  receive add request from 192.168.12.252:9999 and accept it 

以上的指令不列印日志資訊,因為 pgpool 脫離終端了。如果你想顯示 pgpool 日志資訊,你需要傳遞 -n 到 pgpool 指令。此時 pgpool-ii 作為非守護程序模式運作,也就不會脫離終端了。 

$ pgpool -n & 

日志消息會列印到終端,是以推薦使用如下的選項。 

$  /pgpool/bin/pgpool -n -d > /tmp/pgpool.log 2>&1 &    --指令都要帶詳細路徑。 

-d 選項啟用調試資訊生成。 

pgpool -d -n   # 

-d 模式debug下log 

-n 是不使用背景模式 

以上指令持續追加日志消息到 /tmp/pgpool.log 中。如果你需要切換日志檔案,可以将日志傳遞到一個支援日志輪 

換功能的外部指令。例如,你可以使用 apache2 帶的 rotatelogs 工具。 

--pgpool 關閉指令 

[pg93@db2 etc]$ pgpool -m fast stop 

--pgpool reload 指令 

[pg93@db1 etc]$ pgpool reload 

登入檢視,發現這個參數沒辦法顯示: 

[postgres@pgtest01 etc]$ psql -h 192.168.12.251 -p 5432 -u postgres -d postgres 

psql (9.4.5) 

type "help" for help. 

postgres=# show pool_nodes; 

error:  unrecognized configuration parameter "pool_nodes" 

[postgres@pgtest01 etc]$ psql -h 192.168.12.251 -p 9999 -u postgres -d postgres   --注意端口 

node_id |    hostname    | port | status | lb_weight |  role   

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

0       | 192.168.12.251 | 5432 | 2      | 0.500000  | primary 

1       | 192.168.12.252 | 5432 | 3      | 0.500000  | standby 

(2 rows) 

備注: db2 為 primary, db1 為 standby,status 為 2 ,表示正常連接配接; 關于 status 狀态,如下 

    0 - this state is only used during the initialization. pcp will never display it. 

    1 - node is up. no connections yet. 

    2 - node is up. connections are pooled. 

    3 - node is down. 

參數裡面有一個寫錯了,寫成了5433,修改後重新開機pgpool,standby的status依然是3 

[postgres@pgtest01 etc]$ /pgpool/bin/pgpool -m fast stop 

2015-11-19 15:54:42: pid 25448: log:  stop request sent to pgpool. waiting for termination... 

.....done. 

[postgres@pgtest01 etc]$ /pgpool/bin/pgpool 

[postgres@pgtest01 etc]$ 

在從庫上隻看到一條主庫的資訊 

[postgres@pgtest02 pgpool]$ psql -h 192.168.12.252 -p 9999 -u postgres postgres 

0       | 192.168.12.251 | 5432 | 2      | 1.000000  | primary 

(1 row) 

2015-11-19 16:12:38: pid 25943: debug:  watchdog heartbeat: send heartbeat signal to 192.168.12.252:9694 

2015-11-19 16:12:38: pid 25942: debug:  watchdog heartbeat: received heartbeat signal from "192.168.12.252:9999" 

ov 19 16:15:56 pgtest02 pgpool[17626]: [149-1] 2015-11-19 16:15:56: pid 17626: debug:  watchdog heartbeat: received heartbeat signal from "192.168.12.251:9999" 

nov 19 16:15:56 pgtest02 pgpool[17628]: [99-1] 2015-11-19 16:15:56: pid 17628: debug:  watchdog life checking by heartbeat 

nov 19 16:15:56 pgtest02 pgpool[17628]: [99-2] 2015-11-19 16:15:56: pid 17628: detail:  checking pgpool 0 (192.168.12.252:9999) 

nov 19 16:15:56 pgtest02 pgpool[17628]: [100-1] 2015-11-19 16:15:56: pid 17628: debug:  watchdog life checking by heartbeat 

nov 19 16:15:56 pgtest02 pgpool[17628]: [100-2] 2015-11-19 16:15:56: pid 17628: detail:  ok; status 3 

status = 2 正常在使用中,status=3 被移除需要恢複,啟動pg_pool時加入 -d 移除以前的資料庫狀态。 

/pgpool/bin/pgpool -n -d -d  > /tmp/pgpool.log 2>&1 &   兩邊都重新開機一下,帶上-d參數,然後兩台機器看到都正常了。 

1       | 192.168.12.252 | 5432 | 2      | 0.500000  | standby 

六: ha 驗證 

根據上面 show_nodes 輸出, 此時192.168.12.251節點為主庫,192.168.12.252節點為備庫,并且  pgpool 目前跑在192.168.12.251上 

[root@pgtest01 pgpool]# chmod +x failover_stream.sh 

[root@pgtest01 pgpool]# cat failover_stream.sh 

[root@pgtest01 pgpool]# echo $pghome 

添加環境變量 

[root@pgtest01 pgpool]# su - postgres 

[postgres@pgtest01 ~]$ echo $pghome 

[postgres@pgtest01 ~]$ vi .bash_profile 

export path=$path:$home/bin 

export pghome=/pgtina 

export pgdata=/pgtina/data 

1 關 12.251上的資料庫 

12.251關閉資料庫 

[postgres@pgtest01 ~]$ pg_ctl -m fast stop 

waiting for server to shut down.... done 

server stopped 

12.251上檢視 

[postgres@pgtest01 ~]$ pg_controldata |grep cluster 

database cluster state:               shut down 

12.252上檢視 

[postgres@pgtest02 ~]$ pg_controldata |grep cluster 

database cluster state:               in archive recovery 

0       | 192.168.12.251 | 5432 | 3      | 0.500000  | standby 

1       | 192.168.12.252 | 5432 | 2      | 0.500000  | standby    ---沒有變成主庫,可能跟我設定了trigger_file有關系   #trigger_file = '/tmp/pg.trigger.252' 注釋掉 

重新啟動了主庫12.251,發現狀态沒變化,但主庫可以同步,現在再重新開機一次pgpool試試。加上-d 

[postgres@pgtest01 ~]$ /pgpool/bin/pgpool -n -d -d> /tmp/pgpool.log 2>&1 &    恢複了狀态 

再來試試切換: 

[postgres@pgtest01 ~]$ pg_ctl -d /pgtina/data stop 

waiting for server to shut down....... done 

[postgres@pgtest02 data]$ pg_controldata |grep cluster  --12.252 

database cluster state:               in production 

[pg93@db1 etc]$ ll /pgtina/data/recovery.done 

備注:可以看到12.252節點已完成從 standby 角色切換到 primary ,并且 $pgdata/recovery.conf 檔案變成 recovery.done. 

檢視 pgpool 狀态 

[postgres@pgtest01 pgpool]$ psql -h 192.168.12.240 -p 9999 -u postgres postgres   ---使用vip連接配接pgpool 

1       | 192.168.12.252 | 5432 | 2      | 0.500000  | primary 

備注:  12.252已轉換成  primary 角色。 12.251狀态為 3 ,表示 down 狀态。 

接下來以 standby 身份啟動12.251    --注意兩邊的recovery.conf配置内容不一樣喲 

[postgres@pgtest01 data]$ mv recovery.done recovery.conf 

[postgres@pgtest01 data]$ vi recovery.conf 

primary_conninfo = 'host=192.168.12.252 port=5432 user=repluser  password=repluser application_name=standby2' 

啟動新備庫12.151 

[postgres@pgtest01 data]$ pg_ctl -d /pgtina/data start 

server starting 

12.252上操作,添加12.251-新從節點資訊 

[postgres@pgtest02 bin]$ /pgpool/bin/pcp_attach_node -d 5 pgtest01 9898 pgpool pgpool 1   --這裡使用者密碼錯了postgres和密碼123456由之前pcp.conf中設定所得。 

format: 

pcp_attach_node  _timeout_  _host_  _port_  _userid_  _passwd_  _nodeid_ 

把給定的節點加入到 pgpool-ii。 

debug: send: tos="r", len=44 

debug: recv: tos="r", len=63, data=authenticationfailed 

debug: authentication failed. reason=authenticationfailed 

authorizationerror 

認證失敗: 使用者和密碼,還有端口id都不對,要注意看show pool_nodes和pcp.conf中設定的使用者密碼。 

[postgres@pgtest02 bin]$ /pgpool/bin/pcp_attach_node -d 5 pgtest01 9898 postgres test12 0 

debug: send: tos="r", len=46 

debug: recv: tos="r", len=21, data=authenticationok 

debug: send: tos="d", len=6 

debug: recv: tos="c", len=20, data=commandcomplete 

debug: send: tos="x", len=4 

檢視狀态,12.251變成了1,顯然還是有問題:--重新連接配接進去就ok了。 

0       | 192.168.12.251 | 5432 | 2      | 0.500000  | standby 

但是在12.252這邊看又正常了。 

postgres=# show pool_nodes;   ------12.252顯示251是主庫,但12.251顯示252是主庫呀!!!,檢查問題! 

12.251的日志報錯:連不上主庫 

fatal:  could not connect to the primary server: fatal:  no pg_hba.conf entry for replication connection from host "192.168.12.251", user "repluser" 

原來12.252的pg_hba.conf檔案中沒設定權限: 

host    replication    repluser         192.168.12.251/32       md5 

把12.252的pgpool重新開機一次,加上-d參數 

發現顯示終于正常了: 

備注:切換成功!!!!! 

----------------------------------切換步驟總結-------------------------- 

都是在同一台機器上的操作: 

1、確定觸發檔案被注釋掉 

#trigger_file 

2、關閉主庫db 

pg_ctl -m fast stop 

pg_controldata |grep cluster  --檢視狀态(主 shut down ,從 in production--變成了新主) 

psql -h 192.168.12.240 -p 9999 -u pgpool pgpool 

show pool_nodes; 

0       | 192.168.12.251 | 5432 | 2      | 0.500000  | primary  --新主 

1       | 192.168.12.252 | 5432 | 3      | 0.500000  | standby   --新從 

3、将新從添加到pgpool 

mv recovery.done recovery.conf   --修改檔案名 

pg_ctl -d /pgtina/data start    --啟動新從庫 

/pgpool/bin/pcp_attach_node -d 5 pgtest02 9898 postgres test12 1  --注意最後的nodeid和主機名都要對應修改(0,1) 

/pgpool/bin/pcp_attach_node -d 5 pgtest01 9898 postgres test12 0 

正常情況下,這樣就基本切換成功。vip已經可以自己漂移了 

4、如果pgpool狀态不正常,那麼一定要重新開機一下pgpool 

/pgpool/bin/pgpool -m fast stop 

/pgpool/bin/pgpool -n -d -d> /tmp/pgpool.log 2>&1 & 

[postgres@pgtest02 ~]$ the authenticity of host '192.168.12.252 (192.168.12.252)' can't be established.  --切換總是會遇到這個報錯: 

rsa key fingerprint is ad:09:f3:ce:a7:95:c1:e6:39:20:cb:4c:92:13:c0:d2. 

are you sure you want to continue connecting (yes/no)? ------一定要保證root和pg使用者都能ssh到自身和對方主機 

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

2 關pgpool master,測試vip的漂移 

注意:此時12.252是主庫,12.251是從庫,我們去看看之前pgadmin的那個連接配接,是否能讀寫,看連的是主是從,設定的192.168.12.240---5432 

insert into t1 values(999,00,00)   ---報錯:error: cannot execute insert in a read-only transaction   --說明沒有自動漂移到12.252上面 

說明:1、主從的切換,是停主庫pg_ctl -d /pgtina/data stop,pgpool會把從庫自動變成主庫,再對主庫做pcp_attach_node。 

      2、vip的漂移,是将新從庫上的pgpool關閉重新開機,使它漂移到新主庫上去。 

[postgres@pgtest01 pg_log]$ /pgpool/bin/pgpool -m fast stop 

從12.29連接配接過來,發現兩個端口都可以連接配接到資料庫操作。 

[root@antiywh-5nmqmh1 ~]# psql -h 192.168.12.240 -u postgres postgres -p 9999  --使用這個端口連接配接的是pgpool控制台,使用5432就會連接配接到資料庫操作 

tina=# insert into t1 values (9,10,10); 

insert 0 1 

[postgres@pgtest01 data]$ grep ^[a-z] pg_hba.conf 

local   all             all                                     trust 

host    all             all             127.0.0.1/32            trust 

host    all             all             ::1/128                 trust 

host    all             all             192.168.12.252/24       trust   ---限定192.168.12開頭的都可以連接配接進來,要讓192.168.12.240可以連接配接才行。 

host    all             all             0.0.0.0/0               md5 

host    all             all             192.168.10.100/32       md5 

host    replication     repluser        192.168.12.252/32        md5 

pgpool vip :192.168.12.240  從12.251飄到12.252,注意此時僅 pgpool 的 vip 飄移, db1,db2 上的資料庫角色不變, pgpool 的切換非常容易,直接關閉新備庫的pgpool 

[postgres@pgtest02 data]$ psql -h 192.168.12.240 -p 9999 -u postgres postgres 

psql: error:  unable to read message length 

detail:  message length (12) in slot 1 does not match with slot 0(8)    ---因為ip被限制了,連接配接不上。 

3  db1 掉電 power off 

這裡通過 vmwaer 執行 power off 模拟斷電的情況, 在 db1(現在的 primary 節點) 執行  power off ,發現 pgpool  vip 能切換到 db1 ,同時 db1 上的資料庫切換成 primary ,切換成功。 

    第二種,第三種情況就不貼詳細日志了。 

===========================使用者密碼認證登陸測試=================== 

psql: error:  md5 authentication is unsupported in replication, master-slave and parallel modes.   ---需要對12.252完全開放 

hint:  check pg_hba.conf 

注意以下三個檔案: 

/pgtina/data/pg_hba.conf 

/pgpool/etc/pool_hba.conf 

/pgpool/etc/pcp.conf 

/pgpool/etc/pool_passwd 

[postgres@pgtest02 data]$ grep ^[a-z] pg_hba.conf 

local   all             all                                     trust  ---本地不要使用md5,因為需要進行cron的一些任務 

host    all             all             0.0.0.0/0               md5 --全網都必須通過md5認證連進db 

[postgres@pgtest02 etc]$ grep ^[a-z] pool_hba.conf 

local   all         all                               trust 

host    all         all         127.0.0.1/32          trust 

host    all         all         ::1/128               trust 

host    all         all         0.0.0.0/0             md5   ----全網都必須通過md5認證連進pgpool 

[postgres@pgtest02 etc]$ grep ^[a-z] pcp.conf   ----/pgpool/bin/pg_md5 -u postgres -p 

sqluser:d4f1362367d199a64af12b86efee4a09 

fenxi:e020da2d9ffa07b8cbaef98663b48fc6 

pgpool:fa039bd52c3b2090d86b0904021a5e33 

[postgres@pgtest01 etc]$ /pgpool/bin/pg_md5 -m -u postgres -p   ---輸入資料庫密碼 

password: 

[postgres@pgtest01 etc]$ tail pool_passwd   --自動寫入的 

postgres:md503416eb55cdf9cd532c638f12c1918ea   

---終于成功使用密碼登陸,無密碼拒絕通路192.168.12.240:9999  或者251:9999   252:9999 

---無密碼拒絕通路251:5432   252:5432   但是12.240:5432卻可以無密碼連接配接進來!!!(不知道是不是因為5432是db的端口,9999是pgpool的端口 

添加一些其他使用者:sqluser  fenxi  pgpool 

/pgpool/bin/pg_md5 -m -u fenxi -p 

/pgpool/bin/pg_md5 -m -u sqluser -p 

=========================================================================================================================================

su postgres 

createuser -p 5432 pgpool          //在本地的postgresql資料庫建立pgpool使用者 

tina=# create user pgpool login encrypted password 'pgpool123' nosuperuser inherit nocreatedb nocreaterole noreplication; 

createdb -p 5432 -o pgpool pgpool  //在本地的postgresql資料庫建立pgpool資料庫,所有者為pgpool 

[postgres@pgtest02 etc]$ createdb -p 5432 -o pgpool pgpool 

[postgres@pgtest02 etc]$ psql -f /pgpool/share/pgpool-ii/system_db.sql -u pgpool pgpool 

psql:/pgpool/share/pgpool-ii/system_db.sql:3: error:  schema "pgpool_catalog" does not exist 

psql:/pgpool/share/pgpool-ii/system_db.sql:4: error:  schema "pgpool_catalog" does not exist 

psql:/pgpool/share/pgpool-ii/system_db.sql:5: error:  schema "pgpool_catalog" does not exist 

psql:/pgpool/share/pgpool-ii/system_db.sql:6: error:  schema "pgpool_catalog" does not exist 

create schema 

create table 

pgpool=# select tablename from pg_tables where schemaname='pgpool_catalog'; 

   tablename   

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

replicate_def 

dist_def 

query_cache 

/////////////////////////////////////////////////////// 

使用觸發檔案進行主從切換-----可能這種方式不太嚴謹,而且也不利于來回切換: 

主庫故障後,備庫切換成主庫的觸發檔案如下: 

[root@pgtest6 pgpool-ii-pg93]# more failover_stream.sh 

# this script assumes that db node 0 is primary, and 1 is standby. 

# if standby goes down, do nothing. if primary goes down, create a 

# trigger file so that standby takes over primary node. 

# arguments: $1: failed node id. $2: new master hostname. $3: path to 

# trigger file. 

failed_node=$1 

new_master=$2 

trigger_file=$3 

# do nothing if standby goes down. 

if [ $failed_node = 1 ]; then 

fi 

# create the trigger file. 

/usr/bin/ssh -t $new_master /bin/touch $trigger_file 

是以,在pg的postgresql.conf中要賀pgpool參數檔案的定義( /postgres/data/trigger.file)一緻 

不指定-h ,隻指定-p 9999 就可以連上主庫,而不是本地,指定了5432,那就連到本地隻讀庫了。  

[postgres@pgtest01 ~]$ psql -p 5432 -u postgres -d postgres 

postgres=# \c tina 

you are now connected to database "tina" as user "postgres". 

tina=# insert into t1 values(100,100,100); 

error:  cannot execute insert in a read-only transaction    

//////////////////////////////////////////部分參數含義//////////////////////////////////////////// 

我們需要設定用于 pgpool-ii 的背景 postgresql 伺服器了。這些伺服器可以與 pgpool-ii 在同一台主機上,也可以在獨立的主機上。 

如果你決定将所有伺服器都放在同一台主機上,必須為每個服務配置設定不同的端口。如果伺服器被安置在不同的機器上,他 們必須被正确以便可以通過網絡接受 pgpool-ii 的連接配接。 

在本教程中,我們将三台伺服器放在與 pgpool-ii 相同的機器上,分别給它們配置設定端口号 5432,5433,5434。要配置 pgpool-ii,請如下編輯 pgpool.conf。 

backend_hostname0 = 'localhost' 

backend_hostname1 = 'localhost' 

backend_port1 = 5433 

backend_hostname2 = 'localhost' 

backend_port2 = 5434 

backend_weight2 = 1 

分别為 backend_hostname,backend_port,backend_weight 設定節點的主機名,端口号和負載均衡系數。在每個參數串的後面, 

必須通過添加從0開始(例如 0,1,2,…)的整數來指出節點編号。 

backend_weight 參數都為 1 ,這意味着 select 查詢被平均配置設定到三台伺服器上。 

$ pgpool -n 2>&1 | /usr/local/apache2/bin/rotatelogs \ -l -f /var/log/pgpool/pgpool.log.%a 86400 & 

這将生成名稱類似于 “pgpool.log.thursday” 的日志檔案,然後在每天午夜 00:00 輪換日志檔案。如果日志檔案已經存在, 

rotatelogs 将追加日志到這個檔案中。如果想在輪換前删除舊日志檔案,你可以使用 cron: 

55 23 * * * /usr/bin/find /var/log/pgpool -type f -mtime +5 -exec /bin/rm -f '{}' \; 

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

pgpool-ii 通過 show 指令提供一些資訊。show 是一個真實的 sql 語句, 但是如果該指令查詢 pgpool-ii 資訊的話,pgpool-ii 解釋了該指令。可選項如下: 

pool_status, 擷取配置 

pool_nodes, 擷取節點資訊 

pool_processes, 擷取pgpool-ii 程序資訊 

pool_pools, 擷取pgpool-ii 所有的連接配接池資訊 

pool_version, 擷取pgpool_ii 版本資訊 

注意:術語 'pool' 指的是一個 pgpool 程序所擁有的 postgresql 會話池,并非指所有的 pgpool 所擁有的會話。 

sql語句中的 "pool_status" 在以前的版本中已經存在,但是其它可選項在 3.0 中才出現。 

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

pgpool的日志---增長太快,需要輪換,以便删除 

apache的安裝 

軟體:httpd-2.0.64.tar.bz2                 系統:rhel5.5 

apache現在分為兩個版本1.x和2.x,下載下傳位址:http://httpd.apache.org/ 

解壓: 

[root@localhost soft]# tar xvf httpd-2.0.64.tar.bz2 

配置: 

[root@localhost httpd-2.0.64]# ./configure --prefix=/opt/apache2    

/opt/apache2為安裝目錄 

安裝: 

[root@localhost httpd-2.0.64]# make && make install 

啟動: 

[root@localhost /]# /opt/apache2/bin/apachectl start 

停止: 

[root@localhost /]# /opt/apache2/bin/apachectl stop 

如果你需要切換日志檔案,可以将日志傳遞到一個支援日志輪換功能的外部指令。例如,你可以使用 apache2 帶的 rotatelogs 工具。 

-f 選項讓 rotatelogs 在啟動的時候生成一個日志檔案,這個功能随 apache 2.2.9 或更高版本提供。 

這将生成名稱類似于 “pgpool.log.thursday” 的日志檔案,然後在每天午夜 00:00 輪換日志檔案。如果日志檔案已經存在,rotatelogs 将追加日志到這個檔案中。 

如果想在輪換前删除舊日志檔案,你可以使用 cron: 

apache中的cronolog 對你可能有用。 

$ pgpool -n 2>&1 | /usr/sbin/cronolog \ --hardlink=/var/log/pgsql/pgpool.log \ '/var/log/pgsql/%y-%m-%d-pgpool.log' & 

可以建立一個專門存放poollog的目錄,以便删除:(并不需要啟動apache,隻是利用這個自帶工具而已) ---最新的pgpool啟動指令 

/pgpool/bin/pgpool -n -d 2>&1 | /opt/apache2/bin/rotatelogs -l /tmp/pgpool.log.%y%m%d 86400 & 

最後生成的日志格式:/tmp/pgpool.log.20151124 

?轉義符        描述 

%a        簡寫的星期名 

%a        全寫的星期名 

%b        簡寫的月名 

%b        全寫的月名 

%c        日期與時間 

%d        一月中的天,01-31 

%h        時,00-23 

%i        12小時時鐘表示的小時,01-12 

%j        一年中的天,001-366 

%m        一年中的月,01-12 

%m        分,00-59 

%p        a.m或p.m 

%s        秒,00-61 

%u        星期中的天,1-7(星期1為1) 

%u        一年中的星期,01-53(星期日為一個星期的第一天) 

%v        一年中的星期,01-53(星期一為一個星期的第一天) 

%w        一個星期中的天,0-6(星期日為0) 

%x        本地格式日期 

%x        本地格式時間 

%y        小于1900的年号 

%y        年 

%z        時區名字 

%%        a%字元 

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

pcp 指令清單 

pcp 指令是unix指令,通過網絡操作pgpool-ii。 

* pcp_node_count        - 擷取節點數量 

* pcp_node_info         - 擷取節點資訊 

* pcp_proc_count        - 擷取程序清單 

* pcp_proc_info         - 擷取程序資訊 

* pcp_systemdb_info     - 擷取system db資訊 

* pcp_detach_node       - 從pgpool-ii分離一個節點 

* pcp_attach_node       - 給pgpool-ii關聯一個節點 

* pcp_promote_node      - 給pgpool-ii提升一個新的master節點 

* pcp_stop_pgpool       - 停止 pgpool-ii 

其中一個點的參數設定: 

listen_backlog_multiplier = 2 

pcp_listen_addresses = '*' 

log_line_prefix = '%t: pid %p: '   # printf-style string to output at beginning of each log line. 

pid_file_name = '/pgpool/pgpool.pid' 

black_function_list = 'nextval,setval,nextval,setval' 

database_redirect_preference_list = '' 

app_name_redirect_preference_list = '' 

allow_sql_comments = off 

health_check_user = 'repluser' 

health_check_password = 'repluser' 

connect_timeout = 10000 

failover_command = '/pgpool/failover_stream.sh %h ' 

heartbeat_destination0 = '192.168.12.252' 

other_pgpool_hostname0 = '192.168.12.252' 

check_unlogged_table = on 

system_db_password = 'pgpool' 

做了一個pgbouncer和pgpool的測試,過程省略 

測試總結: 

1)pgbouncer的優點:   

pgbouncer非常簡單,也易于修改,當不需要使用的時候,直接停下pgbouncer, 

修改pg的pg_hba.conf 允許所有主機通過md5方式連接配接db即可。 

host  all    all   0.0.0.0/0  md5 

幾乎對db無任何影響,它獨立存在,安裝使用時也不需要進行停庫等操作,隻需要在安裝好之後,通知大家修改端口。 

pgbouncer對性能的損耗也相對較小。 

2)pgbouncer的缺點: 

pgbouncer的功能單一,隻有連接配接池一個功能,不能負載均衡。 

3)pgpool的優點: 

ha,可以在主節點挂掉的情況下,自動遷移,使用者無感覺;負載均衡,可以減輕主節點的壓力,連接配接池,可以避免連接配接數過多造成db hang住,複制和并行暫不介紹 

4)pgpool的缺點: 

性能損耗嚴重,連接配接池的功能不如pgbouncer,不算穩定,出問題的機率比較大