国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

PgSQL · 特性分析 · PG主備流復制機制

2024-07-21 02:51:34
字體:
供稿:網(wǎng)友

PostgreSQL在9.0之后引入了主備流復制機制,通過流復制,備庫不斷的從主庫同步相應的數(shù)據(jù),并在備庫apply每個WAL record,這里的流復制每次傳輸單位是WAL日志的record。而PostgreSQL9.0之前提供的方法是主庫寫完一個WAL日志文件后,才把WAL日志文件傳送到備庫,這樣的方式導致主備延遲特別大。同時PostgreSQL9.0之后提供了Hot Standby,備庫在應用WAL record的同時也能夠提供只讀服務,大大提升了用戶體驗。

主備總體結(jié)構(gòu)

PG主備流復制的核心部分由walsender,walreceiver和startup三個進程組成。walsender進程是用來發(fā)送WAL日志記錄的,執(zhí)行順序如下:

PostgresMain()->exec_replication_command()->StartReplication()->WalSndLoop()->XLogSendPhysical()

walreceiver進程是用來接收WAL日志記錄的,執(zhí)行順序如下:

sigusr1_handler()->StartWalReceiver()->AuxiliaryPRocessMain()->WalReceiverMain()->walrcv_receive()

startup進程是用來apply日志的,執(zhí)行順序如下:

PostmasterMain()->StartupDataBase()->AuxiliaryProcessMain()->StartupProcessMain()->StartupXLOG()

下圖是PG主備總體框架圖:

PG主備總體框架圖

圖1. PG主備總體框架圖

walsender和walreceiver進程流復制過程

walsender和walreceiver交互主要分為以下幾個步驟:

walreceiver啟動后通過recovery.conf文件中的primary_conninfo參數(shù)信息連向主庫,主庫通過連接參數(shù)replication=true啟動walsender進程;walreceiver執(zhí)行identify_system命令,獲取主庫systemid/timeline/xlogpos等信息,執(zhí)行TIMELINE_HISTORY命令拉取history文件;執(zhí)行wal_startstreaming開始啟動流復制,通過walrcv_receive獲取WAL日志,期間也會回應主庫發(fā)過來的心跳信息(接收位點、flush位點、apply位點),向主庫發(fā)送feedback信息(最老的事務id),避免vacuum刪掉備庫正在使用的記錄;執(zhí)行walrcv_endstreaming結(jié)束流復制,等待startup進程更新receiveStart和receiveStartTLI,一旦更新,進入步驟2。PG流復制過程

圖2. PG流復制過程

walreceiver和startup進程

startup進程進入standby模式和apply日志主要過程:

讀取pg_control文件,找到redo位點;讀取recovery.conf,如果配置standby_mode=on則進入standby模式。如果是Hot Standby需要初始化clog、subtrans、事務環(huán)境等。初始化redo資源管理器,比如Heap、Heap2、Database、XLOG等。讀取WAL record,如果record不存在需要調(diào)用XLogPageRead->WaitForWALToBecomeAvailable->RequestXLogStreaming喚醒walreceiver從walsender獲取WAL record。

對讀取的WAL record進行redo,通過record->xl_rmid信息,調(diào)用相應的redo資源管理器進行redo操作。比如heap_redo的XLOG_HEAP_INSERT操作,就是通過record的信息在buffer page中增加一個record:

 MemSet((char *) htup, 0, sizeof(HeapTupleHeaderData)); /* PG73FORMAT: get bitmap [+ padding] [+ oid] + data */ memcpy((char *) htup + offsetof(HeapTupleHeaderData, t_bits), 	   (char *) xlrec + SizeOfHeapInsert + SizeOfHeapHeader, 	   newlen); newlen += offsetof(HeapTupleHeaderData, t_bits); htup->t_infomask2 = xlhdr.t_infomask2; htup->t_infomask = xlhdr.t_infomask; htup->t_hoff = xlhdr.t_hoff; HeapTupleHeaderSetXmin(htup, record->xl_xid); HeapTupleHeaderSetCmin(htup, FirstCommandId); htup->t_ctid = xlrec->target.tid; offnum = PageAddItem(page, (Item) htup, newlen, offnum, true, true); if (offnum == InvalidOffsetNumber) 	elog(PANIC, "heap_insert_redo: failed to add tuple"); freespace = PageGetHeapFreeSpace(page);		/* needed to update FSM below */ PageSetLSN(page, lsn); if (xlrec->flags & XLOG_HEAP_ALL_VISIBLE_CLEARED) 	PageClearAllVisible(page); MarkBufferDirty(buffer);

還有部分redo操作(vacuum產(chǎn)生的record)需要檢查在Hot Standby模式下的查詢沖突,比如某些tuples需要remove,而存在正在執(zhí)行的query可能讀到這些tuples,這樣就會破壞事務隔離級別。通過函數(shù)ResolveRecoveryConflictWithSnapshot檢測沖突,如果發(fā)生沖突,那么就把這個query所在的進程kill掉。

檢查一致性,如果一致了,Hot Standby模式可以接受用戶只讀查詢;更新共享內(nèi)存中XLogCtlData的apply位點和時間線;如果恢復到時間點,時間線或者事務id需要檢查是否恢復到當前目標;回到步驟3,讀取next WAL record。PG rstandby模式和apply日志過程

圖3. PG standby模式和apply日志過程


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 易门县| 枣强县| 芒康县| 资中县| 南京市| 盐城市| 朝阳区| 从江县| 镶黄旗| 临潭县| 临清市| 彭山县| 沙坪坝区| 龙江县| 海口市| 齐河县| 衡山县| 随州市| 横峰县| 新巴尔虎右旗| 靖安县| 泰兴市| 镇康县| 宝应县| 六枝特区| 南漳县| 黄龙县| 乌拉特中旗| 洛南县| 惠安县| 洪江市| 大姚县| 临沧市| 开阳县| 洛扎县| 余江县| 揭东县| 财经| 开鲁县| 濮阳市| 嘉鱼县|