postgresql主從實現之非同步流複製

來源:互聯網
上載者:User

標籤:postgresql主從實現之非同步流複製

postgresql主從複製實現方式之一:
基於Standby的非同步流複製,這是PostgreSQL9.x版本(2010.9)之後提供的一個很nice的功能,類似的功能在Oracle中是11g之後才提供的active dataguard和SQL Server 2012版本之後才提供的記錄傳送,此處再次為pg鼓掌,確實是一個很棒的開來源資料庫。廢話不多說,本篇blog就詳細記錄一下在pg9.5中實現Hot Standby非同步流複製的完整配置過程和注意事項。

Standby資料庫原理:
首先我們做主從同步的目的就是實現db服務的高可用性,通常是一台主要資料庫提供讀寫,然後把資料同步到另一台從庫,然後從庫不斷apply從主庫接收到的資料,從庫不提供寫服務,只提供讀服務。在postgresql中提供讀寫全功能的伺服器稱為primary database或master database,在接收主庫同步資料的同時又能提供讀服務的從程式庫伺服器稱為hot standby server。

PostgreSQL在資料目錄下的pg_xlog子目錄中維護了一個WAL記錄檔,該檔案用於記錄資料庫檔案的每次改變,這種記錄檔機制提供了一種資料庫熱備份的方案,即:在把資料庫使用檔案系統的方式備份出來的同時也把相應的WAL日誌進行備份,即使備份出來的資料區塊不一致,也可以重放WAL日誌把備份的內容推到一致狀態。這也就是基於時間點的備份(Point-in-Time Recovery),簡稱PITR。而把WAL記錄傳送到另一台伺服器有兩種方式,分別是:

    WAL日誌歸檔(base-file)
    流複製(streaming replication)

第一種是寫完一個WAL日誌後,才把WAL記錄檔拷貝到standby資料庫中,簡言之就是通過cp命令實現遠程備份,這樣通常備庫會落後主庫一個WAL記錄檔。而第二種流複製是postgresql9.x之後才提供的新的傳遞WAL日誌的方法,它的好處是只要master庫一產生日誌,就會馬上傳遞到standby庫,同第一種相比有更低的同步延遲,所以我們肯定也會選擇流複製的方法。
在實際操作之前還有一點需要說明就是standby的搭建中最關鍵的一步——在standby中產生master的基礎備份。postgresql9.1之後提供了一個很方便的工具—— pg_basebackup,關於它的詳細介紹和參數說明可以在官網中查看(pg_basebackup tool).下面在搭建過程中再做相關具體說明,關於一些基礎概念和原理先介紹到這裡。
pg_basebackup tool官網介紹:
https://www.postgresql.org/docs/current/static/p-pgbasebackup.html


詳細配置環境:
下面開始實戰,首先準備兩台伺服器,我這裡開了2個虛機做測試,分別是:
主庫(master)CentOS release 6.5 (Final) 10.0.0.100 postgresql 9.5.9
從庫(standby)CentOS release 6.7 (Final) 10.0.0.110 postgresql 9.5.9

從主庫配置開始。
首先要提前在master機器10.0.0.100安裝好postgresql,採用的是二進位安裝包,具體參考本博文的postgresql二進位安裝過程。

主庫配置:
注意此處的操作都是在主庫(10.0.0.100)上進行的,首先開啟資料目錄下的postgresql.conf檔案然後做以下修改:

1.listen_address = ‘*’(預設localhost)
2.port = 10280       (預設是5432)
3.wal_level = hot_standby(預設是minimal)
4.max_wal_senders=2(預設是0)
5.wal_keep_segments=64(預設是0)
下面對上述參數稍作說明
第一個是監聽任何主機,wal_level表示啟動搭建Hot Standby,max_wal_senders則需要設定為一個大於0的數,它表示主庫最多可以有多少個並發的standby資料庫,而最後一個wal_keep_segments也應當設定為一個盡量大的值,以防止主庫產生WAL日誌太快,日誌還沒有來得及傳送到standby就被覆蓋,但是需要考慮磁碟空間允許,一個WAL記錄檔的大小是16M:
[[email protected] data]$ cd /data/pgsql100/data/pg_xlog/
[[email protected] pg_xlog]$ ls
000000010000000000000001  000000010000000000000002  000000010000000000000003  000000010000000000000004  000000010000000000000005  archive_status
[[email protected] pg_xlog]$ du -sh *
16M    000000010000000000000001
16M    000000010000000000000002
16M    000000010000000000000003
16M    000000010000000000000004
16M    000000010000000000000005
4.0K    archive_status
如上,一個WAL記錄檔是16M,如果wal_keep_segments設定為64,也就是說將為standby庫保留64個WAL記錄檔,那麼就會佔用16*64=1GB的磁碟空間,所以需要綜合考慮,在磁碟空間允許的情況下設定大一些,就會減少standby重新搭建的風險。接下來還需要在主庫建立一個超級使用者來專門負責讓standby串連去拖WAL日誌:
CREATE ROLE replica login replication encrypted password ‘replica‘;
接下來開啟資料目錄下的pg_hba.conf檔案然後做以下修改:
[[email protected] pg_xlog]$ tail -2 /data/pgsql100/data/pg_hba.conf
#host    replication     postgres        ::1/128                 trust
host    replication     replica     10.0.0.110/32                md5

如上,這行配置的意思是允許使用者replica從10.0.0.110/32網路上發起到本資料庫的流複製串連,簡言之即允許從程式庫伺服器串連主庫去拖WAL日誌資料。主庫配置很簡單,到此就算結束了,啟動主庫並繼續配置從庫
pg_ctl -D /data/pgsql100/data -l /data/pgsql100/log/postgres.log stop
pg_ctl -D /data/pgsql100/data -l /data/pgsql100/log/postgres.log start

從庫配置:
首先要說明的是從庫上一開始也是需要安裝postgresql資料庫服務的,應為需要pg_basebackup命令工具才能在從庫上產生的master主庫的基礎備份。但是還要強調一點的是:從庫上初始化資料庫時指定的資料目錄/data/psql110/data需要清空,才可以在從庫上使用pg_basebackup命令工具來產生master主庫的基礎備份資料。

從此處開始配置從庫(10.0.0.110),首先要通過pg_basebackup命令列工具在從庫上產生基礎備份:
[[email protected] data]$ pg_basebackup -h 10.0.0.100 -U replica -p 10280 -F p -x -P -R -D /data/psql110/data/ -l replbackup
Password: 密碼(replica)
46256/46256 kB (100%), 1/1 tablespace
[[email protected] data]$
簡單做一下參數說明(可以通過pg_basebackup --help進行查看),
-h指定串連的資料庫的主機名稱或IP地址,這裡就是主庫的ip。
-U指定串連的使用者名稱,此處是我們剛才建立的專門負責流複製的repl使用者。
-F指定了輸出的格式,支援p(原樣輸出)或者t(tar格式輸出)。
-x表示備份開始後,啟動另一個流複製串連從主庫接收WAL日誌。
-P表示允許在備份過程中即時的列印備份的進度。
-R表示會在備份結束後自動產生recovery.conf檔案,這樣也就避免了手動建立。

-D指定把備份寫到哪個目錄,這裡尤其要注意一點就是做基礎備份之前從庫的資料目錄(/data/psql110/data/)目錄需要手動清空。
-l表示指定一個備份的標識。

[[email protected] data]$ cat /data/psql110/data/recovery.conf
standby_mode = ‘on‘
primary_conninfo = ‘user=replica password=replica host=10.0.0.100 port=10280 sslmode=prefer sslcompression=1 krbsrvname=postgres‘

運行命令後看到如下進度提示就說明產生基礎備份成功:
[[email protected] data]$ pg_basebackup -h 10.0.0.100 -U replica -p 10280 -F p -x -P -R -D /data/psql110/data/ -l replbackup
Password: 密碼(replica)
46256/46256 kB (100%), 1/1 tablespace
[[email protected] data]$
如上由於我們在pg_hba.conf中指定的md5認證方式,所以需要輸入密碼。最後還需要修改一下從庫資料目錄下的postgresql.conf檔案,將hot_standby改為啟用狀態,即hot_standby=on。到此為止就算配置結束了,我們現在可以啟動從庫,
[[email protected] data]$ egrep -v ‘^#|^$‘ /data/psql110/data/postgresql.conf|grep "hot_standby"
wal_level = hot_standby            # minimal, archive, hot_standby, or logical
hot_standby = on            # "on" allows queries during recovery

[[email protected] data]$ pg_ctl -D /data/psql110/data -l /data/psql110/log/postgres.log start
server starting

從庫上查看到流複製進程:

[[email protected] data]$ ss -lntup|grep postgres
tcp    LISTEN     0      128                   :::10280                :::*      users:(("postgres",23161,4))
tcp    LISTEN     0      128                    *:10280                 *:*      users:(("postgres",23161,3))
[[email protected] data]$ ps -ef|grep postgres
root       5663   4716  0 18:12 pts/0    00:00:00 su - postgres
postgres   5664   5663  0 18:12 pts/0    00:00:00 -bash
postgres   5855   5664  0 18:13 pts/0    00:00:00 /bin/bash /usr/local/pgsql/bin/psql
postgres   5857   5855  0 18:13 pts/0    00:00:00 /usr/local/pgsql/bin/psql.bin
root      12406   7244  0 18:34 pts/1    00:00:00 su - postgres
postgres  12407  12406  0 18:34 pts/1    00:00:00 -bash
root      13861  13810  0 18:47 pts/3    00:00:00 su - postgres
postgres  13862  13861  0 18:47 pts/3    00:00:00 -bash
root      21768  21736  0 19:54 pts/2    00:00:00 su - postgres
postgres  21769  21768  0 19:54 pts/2    00:00:00 -bash
postgres  23161      1  0 20:05 pts/2    00:00:00 /usr/local/pgsql/bin/postgres -D /data/psql110/data
postgres  23164  23161  0 20:05 ?        00:00:00 postgres: startup process   recovering 000000010000000000000007
postgres  23165  23161  0 20:05 ?        00:00:00 postgres: checkpointer process                     
postgres  23166  23161  0 20:05 ?        00:00:00 postgres: writer process                           
postgres  23167  23161  0 20:05 ?        00:00:00 postgres: stats collector process                  
postgres  23168  23161  0 20:05 ?        00:00:00 postgres: wal receiver process   streaming 0/7000140
postgres  23240  21769  0 20:06 pts/2    00:00:00 ps -ef
postgres  23241  21769  0 20:06 pts/2    00:00:00 grep postgres

主庫上查看到流複製進程:

[[email protected] pg_xlog]$ ps -ef|grep postgres
root       2904   2642  0 00:40 pts/0    00:00:00 su - postgres
postgres   2905   2904  0 00:40 pts/0    00:00:00 -bash
postgres   2939      1  0 00:42 pts/0    00:00:00 /usr/local/pgsql/bin/postgres -D /data/pgsql100/data
postgres   2941   2939  0 00:42 ?        00:00:00 postgres: checkpointer process                      
postgres   2942   2939  0 00:42 ?        00:00:00 postgres: writer process                            
postgres   2943   2939  0 00:42 ?        00:00:00 postgres: wal writer process                        
postgres   2944   2939  0 00:42 ?        00:00:00 postgres: autovacuum launcher process               
postgres   2945   2939  0 00:42 ?        00:00:00 postgres: stats collector process                   
root       3109   3064  0 00:58 pts/2    00:00:00 su - postgres
postgres   3110   3109  0 00:58 pts/2    00:00:00 -bash
postgres   3151   3110  0 00:59 pts/2    00:00:00 /bin/bash /usr/local/pgsql/bin/psql -p10280
postgres   3153   3151  0 00:59 pts/2    00:00:00 /usr/local/pgsql/bin/psql.bin -p10280
root       3189   3087  0 01:07 pts/3    00:00:00 su - postgres
postgres   3190   3189  0 01:07 pts/3    00:00:00 -bash
postgres   3272   2939  0 01:25 ?        00:00:00 postgres: postgres testdb01 [local] idle            
postgres   3415   2939  0 02:16 ?        00:00:00 postgres: wal sender process replica 10.0.0.110(34021) streaming 0/7000140
postgres   3422   3190  0 02:17 pts/3    00:00:00 ps -ef
postgres   3423   3190  0 02:17 pts/3    00:00:00 grep postgres

此時從庫上可以看到流複製的進程,同樣的主庫也能看到該進程。表明主從流複製配置成功。


同步測試示範:
建立庫和建表做測試,在master伺服器(10.0.0.100)中的建立testdb02庫並且建一張表並添加幾條資料:


master上操作:
postgres=# create database testdb02;
CREATE DATABASE
檢查:
[[email protected] pg_xlog]$ psql -p10280 -c ‘\list‘|grep testdb02
 testdb02  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |

testdb01=# \c testdb02
You are now connected to database "testdb02" as user "postgres".
testdb02=# \d
No relations found.
建立表:
CREATE TABLE weather ( city varchar(80), temp_lo int, temp_hi int, prcp real,date date);
testdb02=# \d
          List of relations
 Schema |  Name   | Type  |  Owner   
--------+---------+-------+----------
 public | weather | table | postgres
(1 row)

testdb02=# \d weather
           Table "public.weather"
 Column  |         Type          | Modifiers
---------+-----------------------+-----------
 city    | character varying(80) |
 temp_lo | integer               |
 temp_hi | integer               |
 prcp    | real                  |
 date    | date                  |

testdb02=#
testdb02=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES (‘China05‘, ‘47‘, ‘59‘, ‘1.0‘, ‘1994-12-15‘);
INSERT 0 1
testdb02=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES (‘China04‘, ‘46‘, ‘58‘, ‘2.0‘, ‘1994-12-14‘);\
INSERT 0 1
testdb02=# select * from weather;
  city   | temp_lo | temp_hi | prcp |    date    
---------+---------+---------+------+------------
 China05 |      47 |      59 |    1 | 1994-12-15
 China04 |      46 |      58 |    2 | 1994-12-14
(2 rows)
testdb02=#

從庫上檢查:
[[email protected] data]$  psql -p10280 -c ‘\list‘|grep testdb02
 testdb02  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |

postgres=# \c testdb02;
You are now connected to database "testdb02" as user "postgres".
testdb02=# \d
          List of relations
 Schema |  Name   | Type  |  Owner   
--------+---------+-------+----------
 public | weather | table | postgres
(1 row)

testdb02=# \d weather;
           Table "public.weather"
 Column  |         Type          | Modifiers
---------+-----------------------+-----------
 city    | character varying(80) |
 temp_lo | integer               |
 temp_hi | integer               |
 prcp    | real                  |
 date    | date                  |

testdb02=# select * from weather;
  city   | temp_lo | temp_hi | prcp |    date    
---------+---------+---------+------+------------
 China05 |      47 |      59 |    1 | 1994-12-15
 China04 |      46 |      58 |    2 | 1994-12-14
(2 rows)

testdb02=#
可以看到完美同步,那麼從庫是否能刪除呢?測試一下:
從庫上測試刪除資料庫testdb02;
postgres=# drop database testdb02;
ERROR:  cannot execute DROP DATABASE in a read-only transaction
postgres=# drop database testdb01;
ERROR:  cannot execute DROP DATABASE in a read-only transaction

standby的資料無法刪除,正如我們之前說的,standby只提供唯讀服務,而只有master才能進行讀寫操作,所以master才有許可權刪除資料。master刪除的同時standby中的資料也將同步刪除,

查看複製狀態

主庫中執行

650) this.width=650;" src="https://s4.51cto.com/oss/201710/29/7cdecd8be51e6a025b4afd68ea3b68ed.png-wh_500x0-wm_3-wmp_4-s_675295564.png" title="2222.png" alt="7cdecd8be51e6a025b4afd68ea3b68ed.png-wh_" />

關於非同步流複製的內容到這裡.

參考博文:

http://blog.csdn.net/wzyzzu/article/details/53331206

本文出自 “10931853” 部落格,請務必保留此出處http://wujianwei.blog.51cto.com/10931853/1977210

postgresql主從實現之非同步流複製

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.