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,不算穩定,出問題的機率比較大