這部分純理論內(nèi)容,結(jié)合配圖和數(shù)據(jù)進(jìn)程了解流復(fù)制的工作邏輯。
通過(guò)WAL完成復(fù)制的方式
PostgreSQL在數(shù)據(jù)目錄下的pg_wal(舊版為pg_xlog)子目錄中維護(hù)了一個(gè)WAL日志文件,該文件用于記錄數(shù)據(jù)庫(kù)文件的每次改變,這種日志文件機(jī)制提供了一種數(shù)據(jù)庫(kù)熱備份的方案,即:在把數(shù)據(jù)庫(kù)使用文件系統(tǒng)的方式備份出來(lái)的同時(shí)也把相應(yīng)的WAL日志進(jìn)行備份,即使備份出來(lái)的數(shù)據(jù)塊不一致,也可以重放WAL日志把備份的內(nèi)容推到一致?tīng)顟B(tài)。這也就是基于時(shí)間點(diǎn)的備份(Point-in-Time Recovery),簡(jiǎn)稱(chēng)PITR。
把WAL日志傳送到另一臺(tái)服務(wù)器有兩種方式,分別是:
- WAL日志歸檔(base-file)
寫(xiě)完一個(gè)WAL日志后,才把WAL日志文件拷貝到standby數(shù)據(jù)庫(kù)中,簡(jiǎn)言之就是通過(guò)cp命令實(shí)現(xiàn)遠(yuǎn)程備份,這樣通常備庫(kù)會(huì)落后主庫(kù)一個(gè)WAL日志文件。 - 流復(fù)制(streaming replication)
流復(fù)制是postgresql9.x之后才提供的新的傳遞WAL日志的方法,它的好處是只要master庫(kù)一產(chǎn)生日志,就會(huì)馬上傳遞到standby庫(kù),同第一種相比有更低的同步延遲,所以我們肯定也會(huì)選擇流復(fù)制的方式。
postgresql wal 日志介紹
wal日志即write ahead log預(yù)寫(xiě)式日志,簡(jiǎn)稱(chēng)wal日志。wal日志可以說(shuō)是PostgreSQL中十分重要的部分,相當(dāng)于oracle中的redo日志。
當(dāng)數(shù)據(jù)庫(kù)中數(shù)據(jù)發(fā)生變更時(shí):
change發(fā)生時(shí):先要將變更后內(nèi)容計(jì)入wal buffer中,再將變更后的數(shù)據(jù)寫(xiě)入data buffer;
commit發(fā)生時(shí):wal buffer中數(shù)據(jù)刷新到磁盤(pán);
checkpoint發(fā)生時(shí):將所有data buffer刷新的磁盤(pán)。
如果沒(méi)有wal日志,那么每次更新都會(huì)將數(shù)據(jù)刷到磁盤(pán)上,并且這個(gè)動(dòng)作是隨機(jī)i/o,性能可想而知。并且沒(méi)有wal日志,關(guān)系型數(shù)據(jù)庫(kù)中事務(wù)的ACID如何保證呢?因此wal日志重要性可想而知。其中心思想就是:先寫(xiě)入日志文件,再寫(xiě)入數(shù)據(jù)。
最簡(jiǎn)的主從配置完成后,可以觀察主庫(kù)和從庫(kù)啟動(dòng)的進(jìn)程。
[pg@localhost ~]$ ps -auxf|grep postgres|grep -v grep
pg 31569 0.0 0.4 396536 17048 pts/0 S 10:17 0:00 /usr/pgsql-10/bin/postgres -D /data/db2
pg 31570 0.0 0.0 251456 1952 ? Ss 10:17 0:00 \_ postgres: logger process
pg 31571 0.0 0.0 396632 3416 ? Ss 10:17 0:00 \_ postgres: startup process recovering 000000010000000000000001
pg 31572 0.0 0.0 396536 3704 ? Ss 10:17 0:00 \_ postgres: checkpointer process
pg 31573 0.0 0.0 396536 3212 ? Ss 10:17 0:00 \_ postgres: writer process
pg 31574 0.0 0.0 251452 1988 ? Ss 10:17 0:00 \_ postgres: stats collector process
pg 4314 0.0 0.1 403804 4236 ? Ss 11:41 0:00 \_ postgres: wal receiver process streaming 0/16BEDA0
pg 4304 0.0 0.4 396536 17040 pts/0 S 11:41 0:00 /usr/pgsql-10/bin/postgres -D /data/db1
pg 4305 0.0 0.0 251456 1956 ? Ss 11:41 0:00 \_ postgres: logger process
pg 4307 0.0 0.0 396688 3688 ? Ss 11:41 0:00 \_ postgres: checkpointer process
pg 4308 0.0 0.0 396536 3448 ? Ss 11:41 0:00 \_ postgres: writer process
pg 4309 0.0 0.1 396536 6348 ? Ss 11:41 0:00 \_ postgres: wal writer process
pg 4310 0.0 0.0 396944 3080 ? Ss 11:41 0:00 \_ postgres: autovacuum launcher process
pg 4311 0.0 0.0 251588 2180 ? Ss 11:41 0:00 \_ postgres: stats collector process
pg 4312 0.0 0.0 396828 2520 ? Ss 11:41 0:00 \_ postgres: bgworker: logical replication launcher
pg 4315 0.0 0.0 397328 3568 ? Ss 11:41 0:00 \_ postgres: wal sender process pg ::1(43162) streaming 0/16BEDA0
postgresql主從同步流程
主要分為以下幾個(gè)流程:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-811343.html
- 備庫(kù)啟動(dòng)walreceiver進(jìn)程,walreceiver進(jìn)程向主庫(kù)發(fā)送連接請(qǐng)求。
- 主庫(kù)收到連接請(qǐng)求后啟動(dòng)walsender進(jìn)程,并與walreceiver進(jìn)程建立tcp連接。
- 備庫(kù)walreceiver進(jìn)程發(fā)送最新的wal lsn給主庫(kù)。
- 主庫(kù)進(jìn)行l(wèi)sn對(duì)比,定期向備庫(kù)發(fā)送心跳信息來(lái)確認(rèn)備庫(kù)可用性,并且將沒(méi)有傳遞的wal日志進(jìn)行發(fā)送,同時(shí)調(diào)用SyncRepWaitForLSN()函數(shù)來(lái)獲取鎖存器,并且等待備庫(kù)響應(yīng),鎖存器的釋放時(shí)機(jī)和主備同步模式的選擇有關(guān)。
- 備庫(kù)調(diào)用操作系統(tǒng)write()函數(shù)將wal寫(xiě)入緩存,然后調(diào)用操作系統(tǒng)fsync()函數(shù)將wal刷新到磁盤(pán),然后進(jìn)行wal回放。同時(shí)備庫(kù)向主庫(kù)返回ack信息,ack信息中包含write_lsn、flush_lsn、replay_lsn,這些信息會(huì)發(fā)送給主庫(kù),用以告知主庫(kù)當(dāng)前wal日志在備庫(kù)的應(yīng)用位置及狀態(tài),相關(guān)位置信息可以通過(guò)pg_stat_replication視圖查看。
- 如果啟用了hot_standby_feedback參數(shù),備庫(kù)會(huì)定期向主庫(kù)發(fā)送xmin信息,用以保證主庫(kù)不會(huì)vacuum掉備庫(kù)需要的元組信息
postgresql同步模式
Postgresql數(shù)據(jù)庫(kù)提供了五種同步模式,同步模式主要由synchronous_commit參數(shù)控制。下面簡(jiǎn)單介紹一下五種同步模式的區(qū)別:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-811343.html
- off:對(duì)于本機(jī)wal不用寫(xiě)到磁盤(pán)就可以提交,是異步模式,存在數(shù)據(jù)丟失風(fēng)險(xiǎn)。
- local:不管有沒(méi)有備庫(kù)只需要保證本機(jī)的wal日志刷到磁盤(pán)就行。
- remote_write:等待主庫(kù)日志刷新到磁盤(pán),同時(shí)日志傳遞到備庫(kù)的操作系統(tǒng)緩存中,不需要刷盤(pán)就 能提交,不能避免操作系統(tǒng)崩潰。
- on:如果沒(méi)有備庫(kù),表示wal日志需要刷新到本地的磁盤(pán)中才能提交,如果存在同步備庫(kù)時(shí)(synchronous_standby_name不為空),需要等待遠(yuǎn)程備庫(kù)也刷新到磁盤(pán)主庫(kù)才能提交。
- remote_apply:pg高版本才出來(lái)的功能,備庫(kù)刷盤(pán)并且回放成功,事務(wù)被標(biāo)記為可見(jiàn),用于做負(fù)載均衡,讀寫(xiě)分離等
到了這里,關(guān)于postgresql 流復(fù)制原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!