<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                PostgreSQL在9.0之后引入了主備流復制機制,通過流復制,備庫不斷的從主庫同步相應的數據,并在備庫apply每個WAL record,這里的流復制每次傳輸單位是WAL日志的record。而PostgreSQL9.0之前提供的方法是主庫寫完一個WAL日志文件后,才把WAL日志文件傳送到備庫,這樣的方式導致主備延遲特別大。同時PostgreSQL9.0之后提供了Hot Standby,備庫在應用WAL record的同時也能夠提供只讀服務,大大提升了用戶體驗。 ## 主備總體結構 PG主備流復制的核心部分由walsender,walreceiver和startup三個進程組成。 walsender進程是用來發送WAL日志記錄的,執行順序如下: ~~~ PostgresMain()->exec_replication_command()->StartReplication()->WalSndLoop()->XLogSendPhysical() ~~~ walreceiver進程是用來接收WAL日志記錄的,執行順序如下: ~~~ sigusr1_handler()->StartWalReceiver()->AuxiliaryProcessMain()->WalReceiverMain()->walrcv_receive() ~~~ startup進程是用來apply日志的,執行順序如下: ~~~ PostmasterMain()->StartupDataBase()->AuxiliaryProcessMain()->StartupProcessMain()->StartupXLOG() ~~~ 下圖是PG主備總體框架圖: ![](https://box.kancloud.cn/2015-11-15_5647dfc16eb07.jpg) 圖1\. PG主備總體框架圖 ## walsender和walreceiver進程流復制過程 walsender和walreceiver交互主要分為以下幾個步驟: 1. walreceiver啟動后通過recovery.conf文件中的primary_conninfo參數信息連向主庫,主庫通過連接參數replication=true啟動walsender進程; 2. walreceiver執行identify_system命令,獲取主庫systemid/timeline/xlogpos等信息,執行TIMELINE_HISTORY命令拉取history文件; 3. 執行wal_startstreaming開始啟動流復制,通過walrcv_receive獲取WAL日志,期間也會回應主庫發過來的心跳信息(接收位點、flush位點、apply位點),向主庫發送feedback信息(最老的事務id),避免vacuum刪掉備庫正在使用的記錄; 4. 執行walrcv_endstreaming結束流復制,等待startup進程更新receiveStart和receiveStartTLI,一旦更新,進入步驟2。 ![](https://box.kancloud.cn/2015-11-15_5647dfc183f8f.jpg) 圖2\. PG流復制過程 ## walreceiver和startup進程 startup進程進入standby模式和apply日志主要過程: 1. 讀取pg_control文件,找到redo位點;讀取recovery.conf,如果配置standby_mode=on則進入standby模式。 2. 如果是Hot Standby需要初始化clog、subtrans、事務環境等。初始化redo資源管理器,比如Heap、Heap2、Database、XLOG等。 3. 讀取WAL record,如果record不存在需要調用XLogPageRead->WaitForWALToBecomeAvailable->RequestXLogStreaming喚醒walreceiver從walsender獲取WAL record。 4. 對讀取的WAL record進行redo,通過`record->xl_rmid`信息,調用相應的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產生的record)需要檢查在Hot Standby模式下的查詢沖突,比如某些tuples需要remove,而存在正在執行的query可能讀到這些tuples,這樣就會破壞事務隔離級別。通過函數ResolveRecoveryConflictWithSnapshot檢測沖突,如果發生沖突,那么就把這個query所在的進程kill掉。 5. 檢查一致性,如果一致了,Hot Standby模式可以接受用戶只讀查詢;更新共享內存中XLogCtlData的apply位點和時間線;如果恢復到時間點,時間線或者事務id需要檢查是否恢復到當前目標; 6. 回到步驟3,讀取next WAL record。 ![](https://box.kancloud.cn/2015-11-15_5647dfc1a4665.jpg) 圖3\. PG standby模式和apply日志過程
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看