<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                PG默認每個page的大小為8K,PG數據頁寫入是以page為單位,但是在斷電等情況下,操作系統往往不能保證單個page原子地寫入磁盤,這樣就極有可能導致部分數據塊只寫到4K(操作系統是一般以4K為單位),這些“部分寫”的頁面包含新舊數據的混合。在崩潰后的恢復期間,xlog 里面存儲的記錄變化信息不夠完整,無法完全恢復該頁。PG為了解決這類問題,full_page_write機制孕育而生。 ## 什么是full_page_write? PostgreSQL 在 checkpoint 之后在對數據頁面的第一次寫的時候會將整個數據頁面寫到 xlog 里面。當出現主機斷電或者OS崩潰時,redo操作時通過checksum發現“部分寫”的數據頁,并將xlog中保存的這個完整數據頁覆蓋當前損壞的數據頁,然后再繼續redo就可以恢復整個數據庫了。 除了能夠解決斷電等帶來壞數據頁問題外,full_page_write 還應用在在線備份功能上。PG進行全量備份數據庫一般通過pg_basebackup工具實現,pg_basebackup類似于copy操作,在此期間,也會出現部分數據頁寫到一半時文件被copy走了,正是因為full_page_write存在,備份出來的數據庫才可以成功恢復啟動。所以即便full_page_write=off,在備份時也會被強制自動打開,保證備份成功。 ## 實現原理 full_page_write主要在XLogInsert(插入一條xlog記錄)時發揮作用,通過full_page_writer開關狀態以及是否是checkpoint后對數據頁面的第一次修改(lsn<RedoRecPtr)判斷是否需要備份數據頁。如果需要備份,那么則把數據頁存放在這條記錄的末尾,最終寫入到xlog中。 ~~~ doPageWrites = Insert->fullPageWrites || Insert->forcePageWrites; /* Find info for buffer */ for (i = 0; i < XLR_MAX_BKP_BLOCKS; i++) { if (dtbuf[i] == InvalidBuffer) { /* OK, put it in this slot */ dtbuf[i] = rdt->buffer; if (doPageWrites && XLogCheckBuffer(rdt, true,&(dtbuf_lsn[i]), &(dtbuf_xlg[i]))) { dtbuf_bkp[i] = true; rdt->data = NULL; rdt->len = 0; } break; } ...... } ~~~ 在redo恢復的時候只要數據塊有備份,那么就是用備份的數據。 ~~~ /* If we have a full-page image, restore it and we're done */ if (record->xl_info & XLR_BKP_BLOCK(0)) { (void) RestoreBackupBlock(lsn, record, 0, false, false); return; } ~~~ ![](https://box.kancloud.cn/2015-11-17_564aa53bac10b.jpg) ## full_page_write不足之處 因為full_page_write需要在xlog中記錄數據頁,會寫更多xlog文件,不僅有數據變化信息,還有數據頁本身信息,這樣會增加額外的IO和磁盤消耗,同時也會引起主備延遲變大。 為了優化full_page_write,社區提供了一個patch,它的主要設計是創建兩個共享內存塊隊列,checkpoint專用buffer隊列和非checkpoint專用buffer隊列,同時關閉full_page_write。當用戶DML產生的數據buffer需要刷盤時,并不是立即刷到磁盤,而是先進入double write的buffer隊列,當buffer隊列滿時,則將buffer隊列里面的數據首先刷到特別的double write文件,然后再將數據刷到數據庫文件。通過這種設計就不需要在checkpoint 之后在對數據頁面的第一次寫的時候會將整個數據頁面寫到 xlog 里面。當數據庫需要恢復的時候,遍歷所有double write文件里面的記錄塊,找到每個記錄塊對應的數據庫page,然后對這個page進行checksum,如果page損壞,那么直接把記錄塊里面的內容覆蓋到buffer數據。最后把double write文件刪除,重新初始化buffer隊列。 ![](https://box.kancloud.cn/2015-11-17_564aa53bc0a3c.jpg) ## 總結 把full_page_write這個選項關閉會提高數據庫執行速度以及減少xlog數量,但是可能導致系統崩潰或者掉電之后的數據庫損壞。如果有減小部分頁面寫入風險的硬件支持(比如電池供電的磁盤控制器),或者文件系統支持(能夠保證page寫入原子性),可以把風險降低到一個可以接受的范圍,那么可以考慮關閉這個選項,其他情況下建議打開這個選擇。
                  <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>

                              哎呀哎呀视频在线观看