• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • SQLite3源碼學習(9)Page Cache概述

    標簽: sqlite3  源碼  cache  pager

            Page cache是進程分配的內存空間,用來緩存數據頁面。page cache的管理獨立于操作系統,當一個線程打開一個數據庫連接時就會建立一個page cache,對于一個進程中的多線程,它們可以有獨立的cache也可以共享一個cahce,下圖描述了page cache的結構:

    clip_image002

    Pager初始化時為pPager->pPCache分配了空間,pPCachePCache類型的結構體,其成員變量定義如下:

    struct PCache {
      PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
      PgHdr *pSynced;                     /* Last synced page in dirty page list */
      int nRefSum;                        /* Sum of ref counts over all pages */
      int szCache;                        /* Configured cache size */
      int szSpill;                        /* Size before spilling occurs */
      int szPage;                         /* Size of every page in this cache */
      int szExtra;                        /* Size of extra space for each page */
      u8 bPurgeable;                      /* True if pages are on backing store */
      u8 eCreate;                         /* eCreate value for for xFetch() */
      int (*xStress)(void*,PgHdr*);       /* Call to try make a page clean */
      void *pStress;                      /* Argument to xStress */
      sqlite3_pcache *pCache;             /* Pluggable cache module */
    };

    page cache的一系列管理操作中,pPCache會作為句柄傳入。cache的空間是以一個個slot組織在一起的,這些slot組成一個hash表來存放page。每個在cache里的pagePgHdr結構體來表示:

    struct PgHdr {
      sqlite3_pcache_page *pPage;    /* Pcache object page handle */
      void *pData;                   /* Page data */
      void *pExtra;                  /* Extra content */
      PCache *pCache;                /* PRIVATE: Cache that owns this page */
      PgHdr *pDirty;                 /* Transient list of dirty sorted by pgno */
      Pager *pPager;                 /* The pager this page is part of */
      Pgno pgno;                     /* Page number for this page */
    #ifdef SQLITE_CHECK_PAGES
      u32 pageHash;                  /* Hash of page content */
    #endif
      u16 flags;                     /* PGHDR flags defined below */
     
      /**********************************************************************
      ** Elements above, except pCache, are public.  All that follow are
      ** private to pcache.c and should not be accessed by other modules.
      ** pCache is grouped with the public elements for efficiency.
      */
      i16 nRef;                      /* Number of users of this page */
      PgHdr *pDirtyNext;             /* Next element in list of dirty pages */
      PgHdr *pDirtyPrev;             /* Previous element in list of dirty pages */
    };

    page cache使用的是一種可插入式的cache管理方式,這也就是說page cache先搭建了一個cache的框架,這部分代碼在pcache.c里,而對于slot的具體管理如創建hash表, page的添加刪除和查找、頁面置換算法LRU等操作通過接口來實現,接口定義了一系列相關的函數,sqlite3GlobalConfig.pcache2就是實現這個接口的結構體,其定義如下:

    struct sqlite3_pcache_methods2 {
      int iVersion;
      void *pArg;
      int (*xInit)(void*);
      void (*xShutdown)(void*);
      sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
      void (*xCachesize)(sqlite3_pcache*, int nCachesize);
      int (*xPagecount)(sqlite3_pcache*);
      sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
      void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
      void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
          unsigned oldKey, unsigned newKey);
      void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
      void (*xDestroy)(sqlite3_pcache*);
      void (*xShrink)(sqlite3_pcache*);
    };

    可以看到sqlite3GlobalConfig.pcache2包含了一系列函數指針,通過diaosqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);來初始化。defaultMethods是一個默認的方法,其函數的實現在PCache 1.c

      static const sqlite3_pcache_methods2 defaultMethods = {
        1,                       /* iVersion */
        0,                       /* pArg */
        pcache1Init,             /* xInit */
        pcache1Shutdown,         /* xShutdown */
        pcache1Create,           /* xCreate */
        pcache1Cachesize,        /* xCachesize */
        pcache1Pagecount,        /* xPagecount */
        pcache1Fetch,            /* xFetch */
        pcache1Unpin,            /* xUnpin */
        pcache1Rekey,            /* xRekey */
        pcache1Truncate,         /* xTruncate */
        pcache1Destroy,          /* xDestroy */
        pcache1Shrink            /* xShrink */
      };

    pcache1就相當于page cache的一個插件,在PCache結構體里有如下成員變量sqlite3_pcache *pCachesqlite3_pcache是一個沒有具體定義的結構體,在pcache1插件中,PCache1結構體是一個對sqlite3_pcache重新定義的實體,同時PgHdr也會被重新定義成PgHdr1,下圖可以大致描述pcache1的輪廓

    如果page的數量超過hash表的長度,相同hash值的page會通過鏈表形成一個桶。pinned page表示正在使用的page,不能被回收,unpinned page表示未使用的page,通過一個雙向鏈表連接在一起,當cache滿了后,會通過LRU算法替換掉最久未使用的page

    除了pcache1外,test_pcache.c中還實現了一個簡單的page cache插件testPcache,該插件可以替換來替換pcache1,調用sqlite3_config(SQLITE_CONFIG_PCACHE2, &testPcache)即可替換

    以上圖片都取自SQLite Database System Design and Implementation》

     

    版權聲明:本文為pfysw原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/pfysw/article/details/79177585

    智能推薦

    聊聊Linux 的 Page Cache

    Linux 的 Page Cache 1. Page Cache 1.1 Page Cache 是什么? 為了理解 Page Cache,我們不妨先看一下 Linux 的文件 I/O 系統,如下圖所示: 上圖中,紅色部分為 Page Cache。可見 Page Cache 的本質是由 Linux 內核管理的內存區域。我們通過 mmap 以及 buffered I/O 將文件讀取到內存空間實際上都是...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    猜你喜歡

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    styled-components —— React 中的 CSS 最佳實踐

    https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...

    基于TCP/IP的網絡聊天室用Java來實現

    基于TCP/IP的網絡聊天室實現 開發工具:eclipse 開發環境:jdk1.8 發送端 接收端 工具類 運行截圖...

    精品国产乱码久久久久久蜜桃不卡