数据库系统实现技术实验报告.docx

上传人:b****6 文档编号:7312697 上传时间:2023-01-22 格式:DOCX 页数:16 大小:166.17KB
下载 相关 举报
数据库系统实现技术实验报告.docx_第1页
第1页 / 共16页
数据库系统实现技术实验报告.docx_第2页
第2页 / 共16页
数据库系统实现技术实验报告.docx_第3页
第3页 / 共16页
数据库系统实现技术实验报告.docx_第4页
第4页 / 共16页
数据库系统实现技术实验报告.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

数据库系统实现技术实验报告.docx

《数据库系统实现技术实验报告.docx》由会员分享,可在线阅读,更多相关《数据库系统实现技术实验报告.docx(16页珍藏版)》请在冰豆网上搜索。

数据库系统实现技术实验报告.docx

数据库系统实现技术实验报告

 

数据库实现实验报告

 

题目:

存储&缓冲管理器

姓名:

XXXXXXXXXXXXXXX

学号:

SCXXXXXXXXXXX

院系:

计算机科学与技术学院

 

 

完成日期:

6/6/2012

1系统说明3

1.1术语说明3

1.1.1缓冲区3

1.1.2基于结构的目录文件3

1.2关键技术3

1.2.1内存页面替换策略3

1.2.2页面&存储帧的转换3

1.2.3文件存储格式4

1.3系统需求4

2系统设计4

2.1Hash链表的设计4

2.2系统性能5

2.2.1系能测试方法5

2.2.2性能指标5

2.3系统总体架构6

2.4系统模块6

2.4.1数据存储管理器6

2.4.2缓冲区管理器7

2.4.3LRU管理器8

3模块接口8

3.1缓冲区管理器接口8

3.1.1FixPage(intpage_id,intprot)8

3.1.2FixNewPage()8

3.1.3UnfixPage(intpage_id)8

3.1.4NumFreeFrames()9

3.1.5SelectVictim()9

3.1.6Hash(intpage_id)9

3.1.7RemoveBCB(BCB*ptr,intpage_id)9

3.1.8RemoveLRUEle(intfrid)9

3.1.9SetDirty(intframe_id)9

3.1.10UnsetDirty(intframe_id)9

3.1.11WriteDirtys()9

3.1.12PrintFrame(intframe_id)9

3.2数据存储管理器9

3.2.1OpenFile(stringfilename)9

3.2.2CloseFile()9

3.2.3ReadPage(intpage_id)9

3.2.4WritePage(intframe_id,bFramefrm)10

3.2.5Seek(intoffset,intpos)10

3.2.6GetFile()10

3.2.7IncNumPages()10

3.2.8GetNumPages()10

3.2.9SetUse(intpage_id,intuse_bit)10

3.2.10GetUse(intpage_id)10

3.3LRU管理器10

3.3.1RemoveLRUEle(intfrmid);10

3.3.2ResetFstNode(intframe_id);10

3.3.3Modify(intframe_id);10

4核心算法10

4.1替换页面选择伪代码SelectVictim()10

4.2LRU链表更新Modify(intframe_id)11

5测试结果12

6参考文献:

13

1

系统说明

1.1术语说明

1.1.1缓冲区

缓冲区是指系统的主存中的空间。

CPU只能够访问主存中的内容。

缓冲区包含一组帧片。

当一个页面被请求时,就会被装载到缓冲区中。

大部分的商业数据库管理系统设置帧片的大小与系统的页大小一致以确保不会产生额外的碎片。

本实验采用相同的策略。

缓冲区的大小默认的设置为1024.

缓冲区是由被称之为帧片的逻辑分区组成。

这些帧片被存储在全局的定义的结构当中,通常描述为如下形式:

#defineFRAMESIZE4096

structbFrame

{

Charfield[FRAMESIZE];

};

缓冲区将会存储一系列的存有或者装有页面的帧片。

其数组将如下图

#defineDEFBUFSIZE1024

bFramebuf[DEFBUFSIZE];//或者用户通过参数自定义大小

当页面被请求的时候,这些被分配给缓冲区的空间将会被缓冲区管理器文件等访问。

1.1.2基于结构的目录文件

每一个文件都有一个包含文件中每一页面指针的基础页面。

每一个在基础页面当中的指针都代表一个页面。

数据页面仅仅包含数据而不存储指针。

因此基础页面(也即目录)在文件访问的时候必须被访问。

当记录被查询时候,能够很好地找寻文件是这种基于目录式的文件格式被采用的主要原因。

这种组织方式使得可以快速通过指针访问相应页面而不需要搜索一个长的页面列表。

1.2关键技术

1.2.1内存页面替换策略

采用LRU算法作为替换策略。

通过最近访问时间组织的缓冲区页面构成LRU队列,使用该种策略换出最近最少使用的页面。

总是在LRU的位置选出替换页面。

有一个常系数的时间复杂性是LRU算法的主要优点。

而且,LRU的性能因好的时间局部性而别被人称道。

比如:

当前被访问的页面很可能将不久得将来访问。

对于缓冲区的每一帧片,管理着块的缓冲区必须被保存。

每一个缓冲区控制块(BCB),包含page_id,frame_id,page_latch(页面锁),dirty_bit(脏数据位)。

page_ids作为将page_id作为哈希映射给BCB的关键码。

两个哈希表被需要:

一个是将page_ids映射到frame_id和BCB,一个是将frame_id映射为page_id.

1.2.2页面&存储帧的转换

采用静态的哈希方法。

在静态的哈希方法种种,桶的容量是固定的。

假如一个桶装满,一个溢出的链表将连接性的额外数据。

使用关键值,哈希函数将其映射为一个桶,同时也是访问当个桶的手段。

在程序运行期间,桶的容量不会发生改变。

静态的哈希方法将采用类似相面的函数

H(k)=(page_id)%buffer_size

每一个缓冲区控制块(BCB),page_id,frame_id,计数,dirty_bit(脏数据位)。

将page_id映射到BCB的哈希表如下BCBhTable[BufferSize].将frame_id映射为page_id的哈希表如下inthTable[BufferSize].

1.2.3文件存储格式

为保证可以快速通过指针访问相应页面而不需要搜索一个长的页面列表,每一个文件都有一个包含文件中每一页面指针的基础页面。

每一个在基础页面当中的指针都代表一个页面。

数据页面仅仅包含数据而不存储指针。

因此基础页面(也即目录)在文件访问的时候必须被访问。

1.3系统需求

✓完成数据的读写更新;

✓能够展示实验结果;

✓实现LRU对缓冲区页面的控制;

✓具有一定的容错能力;

✓实验测试的时间;

✓读写命中率以及缺失率。

2系统设计

2.1Hash链表的设计

在实验当中,两处使用hash链表,其中一条链表将page_id映射为frame_id,在实验当中称为ptof;另外一条将frame_id映射为page_id,在实验中成为ftop。

Figure1page_id映射frame_id图

 

Figure2frame_id映射page_id图

2.2系统性能

2.2.1系能测试方法

系统以跟踪驱动文件为主要手段,在该文件由Zipf分布器生成,其中包括500,000个页面,页面号0到49,999。

其形式如“x,###”,其中x是读写标志,0表示读操作,1表示写操作,###表示页面号。

另外假设开始时,内存为空,所有的文件(名为data.dbf)都已经通过目录文件的形式存在物理硬盘。

2.2.2性能指标

i)总I/O次数

ii)缓冲区的命中率

iii)驱动测试文件的运行时间

2.3系统总体架构

2.4系统模块

2.4.1数据存储管理器

classDSMgr{

public:

DSMgr();

intOpenFile(char*filename);

intCloseFile();

intAddPage(intpage_id);

bFrameReadPage(intpage_id);

intWritePage(intpage_id,bFramefrm);

intSeek(intoffset,intpos);

FILE*GetFile();

voidIncNumPages();

voidDecNumPages();//?

?

?

?

?

intGetNumPages();

voidSetUse(intpage_id,intuse_bit);

intGetUse(intpage_id);

intGetRecOffset(intpage_id);

private:

FILE*currFile;

intnumPages;

intpages[MAXPAGES];

voidIsOk(char*filename,intrtn,intexprtn);

};

2.4.2缓冲区管理器

classBMgr

{

public:

BMgr();

~BMgr();

//Interfacefunctions

intFixPage(intpage_id,intrwflag);

voidFixNewPage();

intUnfixPage(intpage_id);

intNumFreeFrames();

//InternalFunctions

intSelectVictim();

intHash(intpage_id);

voidRemoveBCB(BCB*ptr,intpage_id);

voidAddBCB(intframe_id,intrwflag);

voidRemoveLRUEle(intfrid);

voidSetDirty(intframe_id);

voidUnsetDirty(intframe_id);

voidWriteDirtys();

voidPrintFrame(intframe_id);

voidIsOk(char*filename,intrtn,intexprtn);

intGetHits();

intGetIO();

private:

//voidChgPgHash(intpage_id,intframe_id,intoutpgid);

intPageIsUsed(intframe_id);

intChgPgHash(intpage_id,intframe_id);

//HashTable

intftop[DEFBUFSIZE];//frame_idhash

BCB*ptof[DEFBUFSIZE];//pagehash

LRUMgrlrumgr;

DSMgrdsmgr;

bFramefrms[DEFBUFSIZE];//?

?

?

?

intwtPgid;//pagemaxindexwriteondisk

intwrtFlag;//O

intrdFlag;//I

inthits;

intsumIn;

intsumOut;

};

2.4.3LRU管理器

classLRUMgr

{

public:

LRU*header;

LRU*tail;

intused;

LRUMgr(intlruNum);

~LRUMgr();

//intSelectVictim();

intRemoveLRUEle(intfrmid);

voidResetFstNode(intframe_id);

voidModify(intframe_id);

voidIsOk(char*filename,intrtn,intexprtn);

voidDebugShow();

};

3模块接口

3.1缓冲区管理器接口

3.1.1FixPage(intpage_id,intprot)

该函数返回值是frame_id,文件和存储管理器将通过在记录record_id中的page_id找到该页面。

当页面在缓冲区中,函数返回相应的frame_id。

否则调入页面,并且是需要的时候会替换页面。

3.1.2FixNewPage()

该函数原型返回page_id,frame_id。

当因为插入,索引分离,对象创建一个新页面被需要的时候就会调用这个函数,被返回的page_id主要用于被分配给记录record_id和元数据。

找到的新页面将会被文件存储管理器存储新的页面。

3.1.3UnfixPage(intpage_id)

该函数原型返回frame_id,这个函数有一次FixPage或者FixNewPage调用。

这个函数会减少帧片上的固定数量。

如果count减少到0,且页面的锁已被移除,帧片会被移除。

page_id被翻译成frame_id,并且可能没有锁以便能够在count为0时被选为一个替换页面。

3.1.4NumFreeFrames()

该函数原型在缓冲区中查询空闲和可用的帧片,这对于N-way排序的查询处理特别有效。

返回一个从0到BUFFERSIZE-1(1023)的整数。

3.1.5SelectVictim()

该函数挑选一个替换的帧片。

假如被选择的帧上面dirty_bit被设置那么就需要被写到硬盘。

3.1.6Hash(intpage_id)

该函数返回frame_id.

3.1.7RemoveBCB(BCB*ptr,intpage_id)

从一个缓冲区控制块数组中移除page_id的页面。

该函数仅仅在SelectVictim()需要替换页面时被调用。

3.1.8RemoveLRUEle(intfrid)

从列表中移除LRU元素。

3.1.9SetDirty(intframe_id)

函数原型设计帧片的脏数据位。

这个脏数据位表示是否有数据写到缓冲区。

当内容被更改,帧就会被写。

这个包含任何的目录页面和数据页面。

假如bit是1,哪儿表示有数据写入;否则为0。

3.1.10UnsetDirty(intframe_id)

函数原型将相应的frame_id的脏数据置为0,调用这个函数的主要原因是SetDirty被调用时但是页面实际是临时的部分相关。

在这种情况下,这个页面实际上不需要被写。

3.1.11WriteDirtys()

函数在系统关闭时候调用。

主要目的是将buffer中的脏数据帧写到文件。

3.1.12PrintFrame(intframe_id)

打印frame_id里面的内容。

3.2数据存储管理器

3.2.1OpenFile(stringfilename)

函数在文件被打开或者读取的时候调用。

返回值为一个错误返回码。

3.2.2CloseFile()

函数在文件关闭时被调用。

返回值是错误码。

这个函数仅当数据库改变或者程序关闭时候调用。

3.2.3ReadPage(intpage_id)

函数会被缓冲区的FixPage函数调用。

返回的是读取的数据。

这个函数调用fseek()和fread()得到数据。

3.2.4WritePage(intframe_id,bFramefrm)

函数在任何时候从缓冲区中取出数据时调用。

返回被写入的数据字节数。

函数调用fseek()和fwrite()去存储数据。

3.2.5Seek(intoffset,intpos)

函数移动指针

3.2.6GetFile()

函数返回当前文件。

3.2.7IncNumPages()

函数增加页面的计数.

3.2.8GetNumPages()

函数返回文件的计数.

3.2.9SetUse(intpage_id,intuse_bit)

函数找到页数组中的设置位,这个数组跟中被使用的页面。

如果一个页面当中所有的记录都被删除,那么页面就没有实际利用价值并且能够被重新使用。

为了检查页面是否能够被使用,当所有的use_bits被置0。

fixNewPage首先会检查use_bits数组中是否0。

如果有一个0,则可以被重用;否则重新使用。

3.2.10GetUse(intpage_id)

函数返回相应页面的use_bit位。

3.3LRU管理器

3.3.1RemoveLRUEle(intfrmid);

将帧标识为frmid的LRU单元移除

3.3.2ResetFstNode(intframe_id);

把LRU链表当中第一个元素的frame_id重置为传入的参数值;

3.3.3Modify(intframe_id);

将标识为frame_id的LRU单元移到链表首部

4核心算法

4.1替换页面选择伪代码SelectVictim()

当页面不再内存就需要调用替换页,需要根据LRU是否有空闲的单元两种情况进行具体设计。

尤其是当将其他页面换出内存的时候要根据其是否为脏而重写硬盘文件。

……

pLRU=lrumgr.tail;//指向链表的最后一个元素

priorLRU=lrumgr.tail;//指向链表的最后一个元素

frame_id=pLRU->frame_id;//获取最后元素存放的帧ID;

…..

if(frame_id!

=-1){//链表中元素已经全部被用完

while(pLRU!

=lrumgr.header){//寻找未被锁定的帧缓存

flag=PageIsUsed(frame_id);//判断该帧是否锁定

if(flag==1){

frame_id=pLRU->frame_id;

pLRU=pLRU->prior;//transfromtailtoheader

}

else{//找到可用的帧

frame_id=pLRU->frame_id;

pLRU=lrumgr.header;//fakewhile

//break;

}

}

……

lrumgr.Modify(frame_id);//将找到的元素放到链表头部,表示最近被访问

}

else{//链表当中还有元素未被分配

……

lrumgr.Modify(-1);//将最后空闲的元素移动到链表首部

if(lrumgr.used

lrumgr.used++;

return(lrumgr.used-1);

}

}

if(frame_id!

=-1){/调整被替换的元素BCB链表

……

pBCB=ptof[ftop[frame_id]%DEFBUFSIZE];//找到被替换页面的链表的头指针

this->RemoveBCB(pBCB,ftop[frame_id]);//移除替换出去页面的元素

returnframe_id;

}

}

4.2LRU链表更新Modify(intframe_id)

在更新LRU链表过程当中,当要被移动的元素是首元素或者尾元素的时候,需要认真仔细的调整首部或尾部指针,否则会将链表元素丢失

……

LRU*tmp=this->tail;

LRU*tmpFirst=NULL,*tmpLast=NULL;

……

while((tmp!

=NULL)&&(!

(tmp->frame_id==frame_id))){//寻找要移动元素

tmp=tmp->prior;

}……

if(tmp!

=NULL){//要移动的元素存在

tmpFirst=tmp->prior;

tmpLast=tmp->next;

……

if(tmpFirst){//被移动的不是首元素

this->header->prior=tmp;

tmp->next=this->header;

tmp->prior=NULL;//调整链表的头指针

this->header=tmp;//

tmpFirst->next=tmpLast;

if(tmpLast!

=NULL){//被移动的不是尾元素

tmpLast->prior=tmpFirst;//modifythenextLRUElement

分情况}

重置尾指针if(tmpLast==NULL){//frame_id==-1?

orlastnodereplaced

…….

this->tail=tmpFirst;

this->tail->next=NULL;

}

}

}

……

}

5测试结果

测试环境:

linuxUbuntu10.04(LTS)

驱动测试文件的记录数目:

500000

总I/O次数502821

命中率33.9130%

运行时间16min51sec

Figure3实验测试结果

6参考文献:

1DatabaseSystemImplementation(2th),H.Garcia-Molina,J.D.Ullman,J.Widom.机械工业出版社

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1