亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > PostgreSQL > 正文

Postgresql主從異步流復制方案的深入探究

2020-01-31 15:20:58
字體:
來源:轉載
供稿:網友

前言

數據庫的備份工作在日常生產中極為重要,如果你咨詢一個DBA如何才能設計出高可用的數據備份與恢復方案,相信很多人都會從架構上給出很多容災的意見。但歸根到底,如果業務環節中數據庫還牽涉到分布式環境,我認為一個好的方案需要達到三大要求:

  • 多副本
  • 持久化
  • 一致性

日常架構設計中,我們不僅要保證數據額的成功備份,還要保證備份的數據可以快速恢復。在眾多備份恢復可靠性方案中 主從復制 技術,可以說是最常見的實現,本文主要是介紹postgresql主備數據庫的異步流復制的環境搭建與主備切換的操作實踐,除了能把一些基礎的原理運用在日常的數據庫運維中,也可以加深對Postgresql數據庫的底層知識了解。

postgres在9.0之后引入了主從的流復制機制,所謂流復制,就是從服務器通過tcp流從主服務器中同步相應的數據。這樣當主服務器數據丟失時從服務器中仍有備份。

與基于文件日志傳送相比,流復制允許保持從服務器更新。 從服務器連接主服務器,其產生的流WAL記錄到從服務器, 而不需要等待主服務器寫完WAL文件。

PostgreSQL流復制默認是異步的。在主服務器上提交事務和從服務器上變化可見之間有一個小的延遲,這個延遲遠小于基于文件日志傳送,通常1秒能完成。如果主服務器突然崩潰,可能會有少量數據丟失。

同步復制必須等主服務器和從服務器都寫完WAL后才能提交事務。這樣在一定程度上會增加事務的響應時間。

下面的學習與實踐主要針對PostgreSQL的異步流復制(本文沒有涉及到同步復制、邏輯復制等,如果大家想了解其它的備份方案,可以閱讀相關官方文檔或其他資料介紹)。

異步流復制的中心思想是:主庫上提交事務時不需要等待備庫接收WAL日志流并寫入到備庫WAL日志文件時便返回成功,因此異步流復制的TPS會相對同步流復制要高,延遲更低。

環境準備

操作系統 服務器IP 節點名稱 角色
centos 7.2 172.17.0.2 pghost1 主庫
centos 7.2 172.17.0.5 pghost2 備庫

主要目錄規范:

  • 數據目錄: /data/pg10/pg_root
  • 表空間目錄: /data/pg10/pg_tbs
  • 應用程序目錄: /apps/svr/pgsql

要注意的是:編譯安裝Pg我們使用的是root賬戶,但是一般情況下,我們對數據庫的部署操作等應該使用非root的pg超級管理員賬戶,所以需要我們預先創建相關用戶和目錄,并設置相關權限:

$ groupadd postgres$ useradd postgres -g postgres$ passwd postgres$ mkdir -p /data/pg10/pg_root$ mkdir -p /data/pg10/tbs$ chown -R postgres:postgres /data/pg10

實驗用的postgresql為10.0版本

pghost1 和 pghost2 分別下載該版本的源碼安裝包

wget https://ftp.postgresql.org/pub/source/v10.0/postgresql-10.0.tar.gz

下載后進行解壓

tar -zxvf postgresql-10.0.tar.gz

安裝前依賴

由于 configure過程中依賴操作系統包zlib、readline等,所以我實用yum預先安裝:

yum groupinstall "Development tools”yum install -y bison flex readline readline-devel zlib zlib-devel

主備庫數據庫安裝

安裝前,我們先分別對pghost1 和 pghost2創建postgresql的偏好環境變量

vi /etc/profile.d/pgsql.sh

追加以下內容:

export PGPORT=1921export PGUSER=postgresexport PGDATA=/data/pg10/pg_rootexport LANG=en_US.utf8export PGHOME=/apps/svr/pgsqlexport LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/libexport PATH=$PGHOME/bin:$PATH:.export MANPATH=$PGHOME/share/man:$MANPATHalias rm='rm -i'alias ll='ls -lh'

保存文件,并讓環境變量生效:

source /etc/profile.d/pgsql.sh

再進入剛剛解壓的 postgresql-10.0 目錄中,執行以下命令:

./configure ―prefix=/apps/svr/pgsql_10.0/ --with-pgport=1921

之后進行編譯安裝:

gmakegmake install

安裝完成后,我們可以使用以下命令確認是否安裝成功:

$ postgres --versionpostgres (PostgreSQL) 10.0

復制功能部署

在啟動數據庫服務搭建主從結構前,有幾個比較重要的配置文件需要我們額外地進行創建與設置的,它們分別是:

  • postgreql.conf
  • pg_hba.conf
  • recovery.conf
  • .pgpass

下面我們會在實踐中,具體地對上述的文件的配置進行相關說明

上一節,我們編譯安裝好了postgresql,我們接下來切換操作用戶

su postgresql

然后使用initdb工具初始化數據庫:

echo "123456" >> /data/pg10/pgpassinitdb -D /data/pg10/pg_root -E UTF8 --locale=C -U postgres --pwfile=/data/pg10/pgpass

執行上述命令后,在/data/pg10/pg_root目錄下會產生系統數據文件,

PG_VERSION pg_dynshmem pg_multixact pg_snapshots pg_tblspc postgresql.auto.confbase  pg_hba.conf pg_notify pg_stat pg_twophase postgresql.confglobal pg_ident.conf pg_replslot pg_stat_tmp pg_walpg_commit_ts pg_logical pg_serial pg_subtrans pg_xact

之后我們開始配置 /data/pg10/pg_root/postgresql.conf,修改以下幾個關鍵項:

listen_addresses = '*'wal_level = replica  archive_mode = on  archive_command = '/bin/date' max_wal_senders = 10  wal_keep_segments = 512hot_standby = on

注:主庫和備庫的 /data/pg10/pg_root/postgresql.conf 配置建議完全一致

接下來我們在 備庫 上配置 /data/pg10/pg_root/pg_hba.conf

host replication repuser  172.17.0.2/32  md5host replication repuser  172.17.0.5/32  md5

其實最好主庫也配置一份,因為主庫和備庫的角色不是靜止的,在手動或庫出現故障情況下,它們的角色會互相更換。

之后,我們先啟動主庫 pghost1了 (記得切換到postgres用戶):

$ pg_ctl start -D $PGDATA......database system is ready to accept connections doneserver started

使用PostgreSQL的超級管理員postgres登錄到創建流復制用戶repuser,流復制用戶需要有 REPLICATION權限和LOGIN權限

$ psql -U postgres -p 1921psql (10.0)Type "help" for help.postgres=# CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT 5 ENCRYPTED PASSWORD 'domac123';CREATE ROLE

以上命令基本完成主庫上的配置,接下來我們需要熱備生成一個備庫,制作備庫過程中主庫仍然可以讀寫,不影響業務,我們在主庫上創建備份任務:

postgres=# select pg_start_backup('domacli_bak'); pg_start_backup----------------- 0/2000060(1 row)

pg_start_backup() 函數會在主庫上發起一個在線備份,命令執行后,將數據文件壓縮拷貝到備份節點上:

$ tar czvf pg_root.tar.gz pg_root --exclude=pg_root/pg_wal$ scp pg_root.tar.gz postgres@172.17.0.5:/data/pg10

pg_wal目錄不是必須復制的,可以排除這個目錄,以節省空間,然后我們回到備庫的/data/pg10下,執行主庫備份文件的解壓:

$ tar xvf pg_root.tar.gz

解壓后,我們回到主節點,執行停止備份命令,結束這次備份流程

postgres=# select pg_stop_backup();NOTICE: pg_stop_backup complete, all required WAL segments have been archived pg_stop_backup---------------- 0/2000168(1 row)

以上的命令表示完成在線備份,但備庫上扔需要做一些配置,我們回到備庫上,配置 /data/pg10/pg_root/recovery.conf文件,如果該文件不存在,可以執行以下命令,在軟件目錄中復制一個:

cp $PGHOME/share/recovery.conf.sample /data/pg10/pg_root/recovery.conf

備庫的 recovery.conf 配置以下參數

recovery_target_timeline = 'latest'standby_mode = onprimary_conninfo = 'host=172.17.0.2 port=1921 user=repuser'

主要觀察recovery.conf中的參數primary_conninfo 中的 user=repuser, 還記得我們前面在主庫上創建的流傳輸用戶repuser嗎?由于主備直接數據同步需要在用戶下執行操作,而主庫上我們創建repuser的時候,為了安全我設置了密碼, 但recovery.conf我們沒有配置明文密碼,那么程序的密碼如何獲得呢?

我們建議把密碼設置在 ~/.pgpass中:

你也可以直接在上面的recovery.conf 設置 primary_conninfo = ‘host=172.17.0.2 port=1921 user=repuser password=domac123', 但這樣會有安全風險

$ cd ~$ touch .pgpass$ chmod 0600 .pgpass

填寫以下內容:

172.17.0.2:1921:replication:repuser:domac123172.17.0.5:1921:replication:repuser:domac123

好了,當這些備注都就緒之后,我們可以開始啟動我們的備庫了:

$ pg_ctl start...database system is ready to accept read only connections doneserver started

如果備庫正常啟動,我們可以在主備兩庫上觀察WAL發生與接收進程是否都同時工作,以確認異步流工作是否正常工作

主庫上:

ps -ef | grep walpostgres 6939 6935 0 23:16 ? 00:00:00 postgres: wal writer processpostgres 6983 6935 0 23:42 ? 00:00:00 postgres: wal sender process repuser 172.17.0.5(45910) streaming 0/3000140

備庫上:

ps -ef | grep walpostgres 26481 26479 0 23:42 ? 00:00:00 postgres: wal receiver process streaming 0/3000140postgres 26486 26448 0 23:42 ? 00:00:00 grep --color=auto wal

使用 pg_basebackup 方式部署流復制

接下來,介紹一種操作相對簡潔的方式,上述我們配置操作所牽涉到的主要步驟有:

  • pg_start_backup
  • 兩臺服務器之間的數據拷貝
  • pg_stop_backup

以上三個步驟可以合成一步完成,PostgreSQL提供內置的pg_basebackup命令行工具支持對主庫發起一個在線基準備份,并自動進入備份模式進行數據庫基準備份,備份完成后自動從備份模式退出,不需要執行額外的pg_start_backup 和pg_stop_backup 命令顯式地聲明進入備份模式和退出備份模式,pg_basebackup工具是對數據庫實例級進行的物理備份,因此這個工具通常作為備份工具對據庫進行基準備份

pg_basebackup工具發起備份需要超級用戶權限或REPLICATION權限,注意max_wal_senders參數配置,因為pg_basebackup工具將消耗至少一個WAL發送進程。本節將演示通過pg_basebackup工具部署異步流復制,之前已經在pghost2上部署了一個備庫,我們先將這個備庫刪除,之后通過pg_basebackup工具重新做一次備庫,刪除pghost2上的備庫只需要先停備庫之后刪除備庫數據庫數據文件即可,如下所示:

進入pghost2服務器上(172.17.0.5)

$ pg_ctl stop -m fastwaiting for server to shut down.... doneserver stopped$ rm -rf $PGDATA$ rm -rf /data/pg10/pg_tbs

接下來,在pghost2上,使用pg_basebackup觸發基準備份

pg_basebackup -D $PGDATA -Fp -Xs -v -P -h 172.17.0.2 -p 1921 -U repuser -W

執行后,會看到相關的日志輸出

pg_basebackup: initiating base backup, waiting for checkpoint to completepg_basebackup: checkpoint completedpg_basebackup: write-ahead log start point: 0/20007A8 on timeline 1pg_basebackup: starting background WAL receiver22655/22655 kB (100%), 1/1 tablespacepg_basebackup: write-ahead log end point: 0/2000888pg_basebackup: waiting for background process to finish streaming ...pg_basebackup: base backup completed

從以上日志信息看出pg_basebackup命令首先對數據庫做一次checkpoint,之后基于時間點做一個全庫基準備份,全備過程中會拷貝$PGDATA數據文件和表空間文件到備庫節點對應目錄

最后,跟之前使用pg_start_backup的方式一樣,備庫記得配置recovery.conf

recovery_target_timeline = 'latest'standby_mode = onprimary_conninfo = 'host=172.17.0.2 port=1921 user=repuser password=domac123'

如果也配置了pgpass文件,可以使用下屬的配置:

recovery_target_timeline = 'latest'standby_mode = onprimary_conninfo = 'host=172.17.0.2 port=1921 user=repuser'

到此為止,主備的配置基本完成,當然,穩妥起見,我們最好多動手動手,嘗試在主庫上創建并插入數據,觀察備庫上是否同步這些操作,我們再主庫上創建一張表:

postgres=# create table test_ms(id int4);CREATE TABLEpostgres=# insert into test_ms values(6);INSERT 0 1

主庫上,我們創建test_ms表,并插入了一條數據,我們就可以在備庫上進行查詢觀察是否同步成功:

postgres=# select * from test_ms; id---- 6(1 row)

接下來,我們再主庫上,再操作

postgres=# insert into test_ms values(9);INSERT 0 1postgres=# delete from test_ms where id=6;DELETE 1

這個時候,我們發現備庫的數據也都正常同步上了:

postgres=# select * from test_ms; id---- 9(1 row)

那么我們如果在備份上進行數據操作,情況會怎樣呢?我們再備份上執行:

postgres=# insert into test_ms values(6);ERROR: cannot execute INSERT in a read-only transactionSTATEMENT: insert into test_ms values(6);ERROR: cannot execute INSERT in a read-only transaction

觀察這些錯誤日志,我們可以了解到,異步流主從結構中,作為從節點的備庫目前處于的是只讀狀態,它不能進行任何寫入操作。

主備切換

前面介紹了流復制的部署,但要注意的是主庫和備庫的角色不是靜態存在的,在維護過程中可以對兩者的進行角色的切換,舉個例子,當主庫掛掉的時候,需要迅速進行主備切換,讓備庫升級為主庫,原主庫降級到備庫,主備切換是PostgreSQL高可用的基礎,下面就介紹相關的操作。

postgresql 9.0版本流復制只能通過創建文件方式進行主備切換,9.1后,開始支持使用pg_ctl promote觸發方式,相比文件觸發方式操作更方便

操作前,我們先介紹一個系統函數查用來判斷主備角色的方法:

postgres=# select pg_is_in_recovery(); pg_is_in_recovery------------------- f(1 row)

如果返回 f 說明是主庫,返回 t 說明是備庫

pg_ctl promote 切換方式

我們使用以下的步驟進行主備切換:

1、關閉主庫,建議使用 -m fast 模式關閉

$ pg_ctl stop -m fast

2、在備庫上執行pg_ctl promote命令激活備庫,如果recovery.conf變成recovery.done表示備庫已切換成主庫

pg_ctl promote -D $PGDATAwaiting for server to promote....2018-09-30 00:10:30.222 UTC [26480] LOG: received promote requestLOG: redo done at 0/4000028LOG: last completed transaction was at log time 2018-09-29 23:50:52.502513+00LOG: selected new timeline ID: 2LOG: archive recovery completeLOG: database system is ready to accept connectionsSun Sep 30 00:10:30 UTC 2018Sun Sep 30 00:10:30 UTC 2018 doneserver promoted

命令執行后,如果原來的 recovery.conf 更名為 recovery.done, 表示切換成功

3、這時如果需要將老的主庫切換成備庫,在老的主庫的$PGDATA目錄下也創建recovery.conf文件(創建方式跟之前介紹的一樣,內容可以和原從庫pghost2的一樣,只是primary_conninfo的IP換成對端pghost2的IP)

例如,主庫上的 recovery.conf 設置為:

recovery_target_timeline = 'latest'standby_mode = onprimary_conninfo = 'host=172.17.0.5 port=1921 user=repuser password=domac123'

如果要求更高的安全性,可以參考如下配置:

recovery_target_timeline = 'latest'standby_mode = onprimary_conninfo = 'host=172.17.0.5 port=1921 user=repuser'

與此同時,和原備庫pghost2一樣,我們建議把repuser的密碼設置在pghost1 ~/.pgpass中:

$ cd ~$ touch .pgpass$ chmod 0600 .pgpass

填寫以下內容:

172.17.0.2:1921:replication:repuser:domac123172.17.0.5:1921:replication:repuser:domac123

4、啟動老的主庫pghost1,這時觀察主、備進行是否正常,嚴格點可以在新的主庫上對剛才的test_ms表進行操作,觀察數據是否同步成功。

pg_ctl start

我們在新主庫(pghost2)上執行:

postgres=# select pg_is_in_recovery(); pg_is_in_recovery------------------- f(1 row)

發現它目前的角色已經是主庫了, 在新備庫(pghost1)上繼續執行:

postgres=# select pg_is_in_recovery(); pg_is_in_recovery------------------- t(1 row)

發現它目前的角色也已經切換為備庫了

我們再pghost2上,執行數據插入操作:

postgres=# insert into test_ms values(11);INSERT 0 1

這時,pghost1上也觀察到數據同步成功:

postgres=# select * from test_ms; id---- 9 11(2 rows)

到這里為止,主從切換的演練基本完成了

總結

異步流復制模式中,主庫提交的事務不會等待備庫接收WAL日志流并返回確認信息,因此異步流復制模式下主庫與備庫的數據版本上會存在一定的處理延遲,延遲的時間主要受主庫壓力、備庫主機性能、網絡帶寬等影響,當正常情況下,主備的延遲通常在毫秒級的范圍內,當主庫宕機,這個延遲就主要受到故障發現與切換時間的影響而拉長,不過雖然如此,這些數據延遲的問題,可以從架構或相關自動化運維手段不斷優化設置。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久电影观看| 欧美日韩一区二区精品| 亚洲色图激情小说| 91美女片黄在线观| 91久久精品日日躁夜夜躁国产| 亚洲男人天堂2024| 精品一区精品二区| 亚洲网站视频福利| 日日骚久久av| 亚洲图片制服诱惑| 欧美放荡办公室videos4k| 欧美成人午夜激情在线| 日韩视频欧美视频| 欧美激情性做爰免费视频| 久久久国产精品免费| 一区二区三区国产在线观看| 亚洲人成电影网站色xx| 日韩视频在线免费观看| 亚洲成人网在线观看| 日韩欧美极品在线观看| 国产精品网红直播| 欧美日韩亚洲视频一区| 美日韩精品视频免费看| 亚洲最新av在线| 一本色道久久综合亚洲精品小说| 亚洲午夜色婷婷在线| 久久国产精品久久精品| 亚洲成人在线视频播放| 亚洲国产欧美精品| 5278欧美一区二区三区| 日韩在线观看免费高清完整版| 国产精品久久久久久亚洲影视| 精品亚洲va在线va天堂资源站| 川上优av一区二区线观看| 久久在线免费观看视频| 欧美日韩不卡合集视频| 亚洲人成网站在线播| 国产精品精品一区二区三区午夜版| 国产精品三级美女白浆呻吟| 久久久久久久999| 日本乱人伦a精品| 欧美精品videosex性欧美| 亚洲国内精品视频| 国产在线98福利播放视频| 欧美激情精品久久久久久蜜臀| 亚洲一区制服诱惑| 国内伊人久久久久久网站视频| 日韩欧美福利视频| 成人免费视频在线观看超级碰| 欧美一级黑人aaaaaaa做受| 欧洲永久精品大片ww免费漫画| 亚洲精品福利在线| 26uuu亚洲国产精品| 精品国产精品自拍| 国产精品久在线观看| 亚洲一级免费视频| 美女扒开尿口让男人操亚洲视频网站| 日韩av电影免费观看高清| 亚洲天堂网在线观看| 精品视频久久久久久久| 久久中文字幕在线视频| 国产一区二区丝袜高跟鞋图片| 精品高清美女精品国产区| 青青在线视频一区二区三区| 精品欧美国产一区二区三区| 国产精品久久久久久久7电影| 日本精品视频网站| 亚洲性线免费观看视频成熟| 国产一区二区av| 久久天天躁狠狠躁夜夜av| 91精品久久久久久久久久久久久| 欧美午夜片欧美片在线观看| 日韩av中文在线| 亚州欧美日韩中文视频| 欧美韩日一区二区| 精品视频偷偷看在线观看| 成人淫片在线看| 亚洲有声小说3d| 国产午夜精品理论片a级探花| 91精品国产99久久久久久| 亚洲精品福利资源站| 精品偷拍各种wc美女嘘嘘| 日韩hd视频在线观看| 欧美性xxxx| 国产精品999999| 久久久久在线观看| 久热99视频在线观看| 日韩欧美在线播放| 日韩美女中文字幕| 日韩电影在线观看永久视频免费网站| 国产精品一区二区av影院萌芽| 狠狠干狠狠久久| 日韩在线视频中文字幕| 亚洲最大在线视频| 国内精品久久久久| 精品国产成人av| 国产精品国产三级国产专播精品人| 国内外成人免费激情在线视频| 日韩成人在线视频网站| 中日韩美女免费视频网址在线观看| 日韩大陆毛片av| 欧美亚洲日本黄色| 亚洲日韩欧美视频| 中文字幕日本精品| 欧美激情免费在线| 91久久精品国产91久久| 欧洲精品毛片网站| 日韩**中文字幕毛片| 日韩成人激情影院| 欧美成人四级hd版| 日本精品免费观看| 91日韩在线播放| 2019国产精品自在线拍国产不卡| 日韩国产高清污视频在线观看| 综合欧美国产视频二区| 亚洲新中文字幕| 欧洲午夜精品久久久| 最近更新的2019中文字幕| 国语自产精品视频在线看抢先版图片| 亚洲一级免费视频| 日韩在线小视频| 精品亚洲一区二区三区四区五区| 国产精品九九九| 91精品国产综合久久久久久久久| 伊人av综合网| 国产亚洲欧洲高清| 国产成人精品综合久久久| 亚洲最大福利视频| 欧美日韩高清在线观看| 国产精品美女免费看| 亚洲xxxx妇黄裸体| 久久久视频精品| 亚洲影影院av| 亚洲欧美一区二区三区四区| 亚洲成人xxx| 国产亚洲精品美女久久久| 亚洲精品国精品久久99热| 国产精品久久久久一区二区| 欧美性色xo影院| 最近2019中文字幕一页二页| 国产精品美女www爽爽爽视频| 久久人人97超碰精品888| 在线日韩中文字幕| 俺去亚洲欧洲欧美日韩| 国产一区视频在线| 久久人人97超碰精品888| 97av在线影院| 久久成人精品一区二区三区| 亚洲最新av在线| 91av国产在线| 国产精品第一第二| 91大神在线播放精品| 日韩成人av一区| 日韩在线观看免费| 日韩视频在线免费观看| 九九久久久久99精品| 韩国19禁主播vip福利视频| 正在播放亚洲1区| 国产精品久久不能| 夜夜嗨av色综合久久久综合网| 国产成人福利夜色影视| 欧美性精品220| 亚洲无线码在线一区观看| 欧美亚洲午夜视频在线观看|