中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PostgreSQL VFD機制

發布時間:2020-06-17 15:38:41 來源:網絡 閱讀:2081 作者:yzs的專欄 欄目:數據庫

1、結構體

VFD機制中由結構體struct vfd來維護。其中各個成員變量的意義如下表所示:

fd

vfd實際對應的物理文件文件描述符

fdstate

FD_DELETE_AT_CLOSE:表示文件在關閉時需刪除

FD_TEMP_FILE_LIMIT:標記臨時文件

FD_CLOSE_AT_EOXACT

這幾個都針對臨時文件

resowner

owner, for automatic cleanup

nextFree

VFDfree鏈表,實際上是數組的下標。

lruMoreRecently

VFD的最近最少使用鏈表,為雙向。實際上也是數組的下標

lruLe***ecently

lruLe***ecently為正向,每次插入都插入頭部

fileSize

文件大小

fileName

文件名

fileFlags

打開文件時的標簽,比如O_CREATE

fileMode

打開文件時的屬性,比如讀寫權限等

2、初始化

啟動時初始化,使用malloc,只在本進程中有效,即每個進程都維護各自的VfdCache而并非共享內存。初始化時只申請第一個數組,并將其fd置為VFD_CLOSED

PostgresMain->BaseInit->InitFileAccess:
????VfdCache?=?(Vfd?*)?malloc(sizeof(Vfd));
????MemSet((char?*)?&(VfdCache[0]),?0,?sizeof(Vfd));
????VfdCache->fd?=?VFD_CLOSED;
????SizeVfdCache?=?1;

2、open時的流程

1Open時首先會調用AllocateVfd,從VfdCache數組中找一個空閑的slot,然后返回。該函數流程見AllocateVfd調用。

2)然后會調用ReleaseLruFiles判斷是否open了最大限制的fd。如超出限制,則將LRU鏈表最后一個VFDfd close掉。

3open文件,并將該VFD插入到LRU鏈表。插入LRU的函數Insert詳細流程看下面的函數分析。

4)然后對vfdP成員變量進行賦值。

PathNameOpenFilePerm->
????file?=?AllocateVfd();
????vfdP?=?&VfdCache[file];
????ReleaseLruFiles();
????vfdP->fd?=?BasicOpenFilePerm(fileName,?fileFlags,?fileMode);
????Insert(file);
????vfdP->fileName?=?fnamecopy;
????/*?Saved?flags?are?adjusted?to?be?OK?for?re-opening?file?*/
????vfdP->fileFlags?=?fileFlags?&?~(O_CREAT?|?O_TRUNC?|?O_EXCL);
????vfdP->fileMode?=?fileMode;
????vfdP->fileSize?=?0;
????vfdP->fdstate?=?0x0;
????vfdP->resowner?=?NULL;

AllocateVfd

1)每次調用BasicOpenFilePerm open文件前都會調用AllocateVfdVfdCache中獲取一個空閑的vfd

2)首先會判斷free鏈表中是否為空。初始時刻,SizeVfdCache1,則會將VfdCache初始化成大小32的數組,并將其通過nextFree串聯起來形成free鏈表,注意該free鏈表為循環。

3VfdCache[0]不使用。最開始32個的時候,即第一次擴充后free 鏈表如下圖所示,跳過VfdCache[1]1會返回。也就是說每次取VFD都是 VfdCache[0].nextFree

4)后續再次擴充時,都是翻倍進行擴充

AllocateVfd->
????if?(VfdCache[0].nextFree?==?0){
????????Size??newCacheSize?=?SizeVfdCache?*?2;
????????if?(newCacheSize?<?32)
????????????newCacheSize?=?32;
????????newVfdCache?=?(Vfd?*)?realloc(VfdCache,?sizeof(Vfd)?*?newCacheSize);
????????VfdCache?=?newVfdCache;
????????for?(i?=?SizeVfdCache;?i?<?newCacheSize;?i++){
????????????MemSet((char?*)?&(VfdCache[i]),?0,?sizeof(Vfd));
????????????VfdCache[i].nextFree?=?i?+?1;
????????????VfdCache[i].fd?=?VFD_CLOSED;
????????}
????????VfdCache[newCacheSize?-?1].nextFree?=?0;
????????VfdCache[0].nextFree?=?SizeVfdCache;
????????SizeVfdCache?=?newCacheSize;
????}
????file?=?VfdCache[0].nextFree;
????VfdCache[0].nextFree?=?VfdCache[file].nextFree;
????return?file;

PostgreSQL VFD機制

ReleaseLruFiles

1nfileopen打開的文件數,numAllocatedDescsfopen打開的文件數,max_safe_fds為操作系統計算得出的值。

2)一旦超出max_safe_fds值,就會調用ReleaseLruFileLRU鏈表刪除一個,注意刪除的是VfdCache[0].lruMoreRecently,即鏈表的尾部,最近最少使用的。

3首先將該fd關閉,然后將之置為VFD_CLOSED。調用Delete函數將VFDLRU鏈表刪除。注意這里只是從LRU鏈表刪除,不會釋放回收到free鏈表,也不會修改vfd數據結構的其他成員變量值。因為后續可能還會用到該物理文件,會重新open并將之重新insertLRU鏈表。

ReleaseLruFiles->
????while?(nfile?+?numAllocatedDescs?>=?max_safe_fds){
????????if?(!ReleaseLruFile())
???????????break;
????}
ReleaseLruFile->
????LruDelete(VfdCache[0].lruMoreRecently);->
????????vfdP?=?&VfdCache[file];
????????close(vfdP->fd);
????????vfdP->fd?=?VFD_CLOSED;
????????--nfile;
????????Delete(file);-->
????????????vfdP?=?&VfdCache[file];
????????????VfdCache[vfdP->lruLe***ecently].lruMoreRecently?=?vfdP->lruMoreRecently;
????????????VfdCache[vfdP->lruMoreRecently].lruLe***ecently?=?vfdP->lruLe***ecently;

3、Insert

Insert->
????vfdP?=?&VfdCache[file];
????vfdP->lruMoreRecently?=?0;
????vfdP->lruLe***ecently?=?VfdCache[0].lruLe***ecently;
????VfdCache[0].lruLe***ecently?=?file;
????VfdCache[vfdP->lruLe***ecently].lruMoreRecently?=?file;

?

LRU鏈表的形式如下:

PostgreSQL VFD機制

Insert一個VFD時:

PostgreSQL VFD機制

4、Delete

Delete(file);-->
????vfdP?=?&VfdCache[file];
????VfdCache[vfdP->lruLe***ecently].lruMoreRecently?=?vfdP->lruMoreRecently;
????VfdCache[vfdP->lruMoreRecently].lruLe***ecently?=?vfdP->lruLe***ecently;

例如刪除VfdCache[1]

PostgreSQL VFD機制

5、回收VFD

1)每次調用FileClose時,會回收vfdfree鏈表。

2)先調用close函數

3)然后將之從LRU鏈表刪除

4)如果是臨時文件,還會將臨時文件刪除

5)調用FreeVfdvfd回收到free鏈表

FileClose->
????close(vfdP->fd);
????--nfile;
????vfdP->fd?=?VFD_CLOSED;
????Delete(file);
????...
????FreeVfd(file);

?

FreeVfd

調用函數FreeVfd回收,注意幾個成員變量的修改。回收時,將之插入到free鏈表頭部。注意每次取時也從頭部取

FreeVfd->
????free(vfdP->fileName);//注意fileName需要釋放,他是另malloc的
????vfdP->fileName?=?NULL;
????vfdP->fdstate?=?0x0;
????vfdP->nextFree?=?VfdCache[0].nextFree;
????VfdCache[0].nextFree?=?file;


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁津县| 怀宁县| 伊宁县| 济宁市| 关岭| 灵丘县| 东兴市| 遵义市| 绵竹市| 崇礼县| 响水县| 谷城县| 洪泽县| 景洪市| 万全县| 炉霍县| 顺义区| 乐清市| 平度市| 定襄县| 峡江县| 江永县| 祁东县| 孟连| 丰台区| 贡山| 普兰县| 永清县| 清水河县| 文成县| 瓦房店市| 古田县| 城市| 黄龙县| 绵竹市| 池州市| 桃园市| 武城县| 板桥市| 胶南市| 兴宁市|