从虚拟文件系统VFS到虚拟数据库管理系统VDBMS.docx
- 文档编号:8203627
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:13
- 大小:274.55KB
从虚拟文件系统VFS到虚拟数据库管理系统VDBMS.docx
《从虚拟文件系统VFS到虚拟数据库管理系统VDBMS.docx》由会员分享,可在线阅读,更多相关《从虚拟文件系统VFS到虚拟数据库管理系统VDBMS.docx(13页珍藏版)》请在冰豆网上搜索。
从虚拟文件系统VFS到虚拟数据库管理系统VDBMS
从虚拟文件系统(VFS)到虚拟数据库管理系统(VDBMS)
摘要:
本文主体分为两个部分,第一部分为虚拟文件系统(VirtualFileSystem),第二部分为虚拟数据库管理系统(VirtualDatabaseManagementSystem)。
第一部分中,首先介绍Linux中VFS的抽象分层模型,然后分析四个结构体对象,并说明其中联系,最后简要介绍VFS系统工作方式以及结构上的优点。
第二部分中,首先介绍虚拟数据库的体系结构,然后分析基于XML的VDBMS中异构数据集成的思想和实现框架。
关键词:
Linux;虚拟文件系统(VFS);虚拟数据库管理系统(VDBMS)异构数据源
0引言:
传统的操作系统仅能支持一种类型的文件系统,随着信息技术的发展和应用需求的增长,对文件系统的使用提出了新的要求。
为了能同时支持多种文件系统,不同操作系统采用不同技术方案来提供虚拟文件系统,它要实现以下目标:
把多种个文件系统纳入统一框架中,不同的磁盘分区可以包含不同的文件系统,对它们的使用和传统单一文件系统没有区别;用户可以通过同一组系统调用来对不同的文件系统及文件进行操作,更进一步,系统调用可以跨物理介质和跨文件系统执行,如从一个文件系统拷贝或移动数据到另一个文件系统;对网络共享文件提供完全支持,访问远程节点上的文件应与访问本地节点的文件一致;开发出新的文件系统后,可以模块方式加入到操作系统中。
VFS是内核的一个子系统,提供了一个通用文件系统模型,该模型囊括了所能见到的文件系统常用功能和行为,并为应用程序提供一致性的文件系统接口,安装的所有物理文件系统不但依赖于VFS共存,而且也依靠VFS协同工作。
目前,大部分数据分布在Web站点、文件系统、数据库系统和各种应用程序之中,并由此形成了各种各样分布分散和形式不一的数据源,即异构数据源。
虚拟数据系统(VDB)可将各种外部数据源作为企业关系数据系统的一个扩充,提供一个把分散数据收集起来的方案。
通过VDBMS,向用户提供统一的数据视图和查询接口。
屏蔽底层数据库的位置信息和平台差异,实现了异构数据库的无缝连接。
1VFS
1.1VFS的分层抽象
VFS分层抽象主要设计思想有以下3点:
(1)应用层:
VFS模型源于UNIX文件系统,使得用户可以直接使用标准UNIX文件系统调用来操作文件,无需考虑具体文件系统特性和物理存储介质,通过VFS访问文件系统,才使得不同文件系统之间的协作性和通用性成为可能。
(2)虚拟层:
在对所有具体文件系统的共同特性进行抽象的基础上,形成一个与具体文件系统实现无关的虚拟层,并在此层次上定义与用户的一致性接口;
(3)实现层:
该层使用类似开关表技术进行具体文件系统转接,实现各种文件系统的物理操作细节,每个文件系统是自包含的,包含文件系统实现的各种设施,如超级块、节点区、数据区以及各种数据结构和文件类的操作函数。
图1为VFS的分层结构
图1
1.2VFS中主要结构体对象
(1)超级块对象(SuperBlock)。
各种文件系统都必须实现超级块。
该对象用于存储特定文件系统的信息,通常对应于存放在磁盘特定扇区中的文件系统超级块或文件系统控制块。
超级块对象由SuperBlock结构体表示。
下面给出它的部分数据结构和域的描述:
structsuper_block
{
structlist_heads_list;//指向超级块链表的指针
kdev_ts_dev;//文件系统的主、次设备号
unsignedlongs_blocksize;//字节为单位的块大小
unsignedchars_blocksize_bits;//以2的幂次表示块大小,如块为4KB,值为12
…
structfile_system_type*s_type;//指向文件系统file_system_type结构的指针
structsuper_operations*s_op;//指向具体文件系统的用于超级块操作的函数集
structdentrys_root;//安装目录的dentry对象
…
union
{//一个联合体,成员是各个具体文件系统的fsname_sb_info数据结构
structminix_sb_infominix_sb;
structext2_sb_infoext2_sb;
structhpfs_sb_infohpfs_sb;
…
}u;
};
每个被安装的文件系统都有一个super_block结构,以环形双向链表把它们链接在一起,指向该链表第一个元素和最后一个元素的指针存放在该超级块的成员s_list域中。
联合体中的成员super_block.u是实现支持多种文件系统的关键,它指向Linux文件系统所支持的各种具体文件系统的超级块,当系统上安装另一个文件系统时,那么磁盘上的hpfs的超级块被复制到内存的hpfs_sb_info结构体中,由super_block.u.hpfs_sb指向该结构体,此后允许该文件系统直接对内存超级块的u联合体操作,无需再去读盘。
与超级块关联的方法就是超级块操作对象,这些操作由super_operation结构来描述:
structsuper_operation{
viod(*write_super)(structsuper_block*);//把超级块信息写回磁盘
viod(*put_super)(structsuper_block*);//释放超级块对象
viod(*read_inode)(structinode*);//读取文件inode
viod(*write_inode)(structinode*,int);//回写文件inode
viod(*put_inode)(structinode*);//逻辑上释放inode
viod(*delete_inode)(structinode*);//物理上释放inode
…
};
结构体中的每一项是一个指向超级块操作函数的指针,而超级块操作函数执行文件系统和索引节点的低层操作。
(2)索引节点对象(inode)
Linux通过索引节点对象来管理文件系统中的所有对象。
索引节点对象包含了内核在操作文件或目录时需要的全部信息。
一个索引节点对象可以引用一个文件、目录或另一个对象的符号链接。
每个文件系统包含一个位于磁盘上的索引节点对象。
索引节点对象由inode结构体表示。
下面给出它的部分数据结构和域的描述:
structinode
{
structlist_headi_hash;//指向散列链表的指针
structlist_headi_list;//指向索引节点链表的指针
structlist_headi_dentry;//指向目录项链表的指针
…
unsignedlongi_ino;//inode号
kdevtidev;//常规文件所在设备号
umode_ti_mode;//文件类型以及存取权限
nlink_ti_nlink;//连接到该inode的硬连接数
uid_ti_uid;//文件属主的用户ID
gid_ti_gid;//文件属主所在组的ID
kdev_ti_rdev;//特殊文件所在设备号
loff_ti_size;//字节为单位文件大小
…
structinode_operations*i_op;//指向inode进行操作的函数指针
structsuper_block*i_sb;//指向该文件系统超级块的指针
atomic_ti_count;//当前使用该inode的引用计数,0表示空闲
structfile_operations*i_fop;//指向文件操作操作的指针
…
structpage*i_pages;//指向页结构的指针
unsignedlongi_state;//索引节点状态
unsignedinti_flags;//文件系统安装标志
…
union
{//联合体成员指向具体文件系统的inode结构
structminix_inode_infominix_i;
structExt2_inode_infoExt2_i;
structhpfs_inode_infohpfs_i;
…
}u;
};
一个索引节点代表文件系统中的一个文件,它也可以是设备、套接字或管道这类特殊文件,故索引节点中会包含特殊的项。
与索引节点关联的方法就是索引节点操作对象,这些操作由inode_operation结构来描述:
structinode_operation{
int(*create)(structinode*,structdentry*,int);
structdentry*(*loopup)(structinode*,structdentry*);
int(*link)(structdentry*,structdentry*);
int(*symlink)(structinode*,structdentry*,constchar*);
int(*mkdir)(structinode*,structdentry*,int);
int(*rmdir)(structinode*,structdentry*);
…
};
其中,主要函数功能如下:
create()创建一个新的inode,loopup()查找一个inode所在的目录,link()和unlink()创建和删除一个硬连接,symlink()为符号链接创建一个inode,mkdir()和rmdir()为目录项创建和删除一个inode。
(3)目录项对象(dentry)
文件系统的层次结构由VFS中的目录项对象管理。
文件系统有一个根目录项对象。
它是唯一没有父对象的目录项对象。
目录项对象由dentry结构体表示。
下面给出它的部分结构和域的描述:
Structdentry{
Atomic_td_count;//目录项dentry引用计数
unsignedintd_flags;//dentry状态标志
structinode*d_inode;//与文件关联的索引节点
structdentry*d_parent;//父目录的dentry结构
structlist_headd_hash;//dentry形成的哈希表
structlist_headd_lru;//未用的LRU双向链表
structlist_headd_child;//父目录的子目录项dentry形成双向链表
structlist_headd_subdirs;//该目录项的子目录形成的双向链表
structlist_headd_alias;//索引节点别名的链表
intd_mounted;//目录项的安装点
structqstrd_name;//目录项名,用于快速查找
unsignedlongd_time;//重新生效时间
structdentry_operations*d_op;//操作目录项的函数
structsuper_block*d_sb;//目录项树的根
void*d_fsdata;//文件系统特殊数据
unsignedchard_iname[DNAME_INLINE_LEN];//文件名前16个字符
…
};
一个有效的dentry结构必定对应一个inode结构,这是因为目录项要么代表一个目录,要么代表一个文件,目录实际上也是文件。
所以,只要dentry结构有效,则其指针d_inode必定指向一个inode结构。
反之不然,一个inode可能对应多个dentry结构,也就是说,一个文件可以有多个文件名或路径名,这是因为一个已经建立的文件可以被链接(link)到其他文件名。
所以在inode结构中有一个队列i_dentry,凡代表同一个文件的所有目录项都通过其dentry结构中的d_alias域拉构体入相应inode结构中的i_dentry队列。
在内核中有一个散列表dentry_hashtable,是一个list_head的指针数组,一旦在内存中建立一个目录节点的dentry结构,就通过它的d_hash域链入散列表中的某个队列中。
内核中还有一个队列dentry_unused,凡是已经没有用户使用的dentry结构就通过其d_lru域挂入空闲队列。
Dentry结构中除资d_alias、d_hash和d_lru三个队列外,还有d_VFSmntd_child及d_subdirs队列,第一个仅在dentry为安装点时使用;当该目录节点有父目录时,则其dentry结构就通过d_child挂入其父节点的d_subdires队列中,同时,又过d_parent指向其父目录的dentry结构,而它自己各个子目录的dentry结构则挂在其d_subdirs域指向的队列中。
可见一个文件系统中所有目录项结构,或组织成一个散列表,或组织成一颗树,或组织成一个链表,这将为文件访问和文件路径搜索奠定良好基础。
与目录项关联的方法就是目录项操作对象,这些操作由dentry_operation结构来描述:
structdentry_operation{
int(*d_revalidate)(structdentry*,int);
int(*d_hash)(structdentry*,structqstr*);
int(*d_compare)(structdentry*,structqstr*,structqstr*);
int(*d_delete)(structdentry*);
int(*d_release)(structdentry*);
int(*d_iput)(structdentry*,structinode*);
…
};
其中,主要函数功能如下:
d_revalidate()判定目录项是否有效,d_hash()生成一个散列值,d_compare()比较两个文件名,d_delete()删除d_count为0的目录项对象,d_release()释放一个目录项对象,d_iput()丢弃目录项对应的索引节点。
(4)文件对象(file)
在Linux系统中打开的每个文件都存在一个文件对象。
文件对象是已打开的文件在内存中的表示。
虽然一个文件对应的文件对象不是唯一的。
但对应的索引节点和目录项对象是唯一的。
文件对象由file结构体表示。
下面给出它的部分结构和域的描述:
structfile{
structlist_headf_list;//所有打开文件形成的链
structdentry*f_dentry;//指向相关目录项的指针
structVFSmount*f_VFSmnt;//指向VFS安装点的指针
structfile_operation*f_op;//指向文件操作表的指针
mode_tf_mode;//文件打开模式
loff_tf_pos;//文件当前位置
unsignedshortf_flags;//打开文件时指定的标志
unsignedshortf_count;//使用此结构的进程数
…
};
每个文件对象总是包含在下列中的一个双向环形链表中:
·“未使用”文件对象链表该链表可以用做文件对象的内存缓冲区,通常设置为可放10个对象,且其中必须包含NR_RESERVED_FILES对象。
·“正在使用”文件对象链表该链表中的每个元素至少由一个进程在使用,故各个元素的f_count域必定非空。
如果VFS需要分配一个新的文件对象,就调用函数get_empty_file(),它检测“未使用”文件对象链表的元素是否多于NR_RESERVED_FILES,如果是,则选一个元素使用,否则退回到正常的内存分配。
与文件关联的方法就是文件操作对象,这些操作由file_operation结构来描述:
structfile_operation{
loff_t(*llseek)(structfile*,loff_t,int);
ssize_t(*read)(structfile*,char*,size_t,loff_t*);
ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);
int(*mmap)(structfile*,structvm_area_struct*);
int(*open)(structinode*,structfile*);
int(*fiush)(structfile*);
int(*release)(structdentry*);
int(*fsync)(structfile*,structdentry*,intdatasync);
…
};
其中,主要函数功能如下:
llseek()修改文件指针,read()从文件中读出若干字节,write()向文件中写入若干字节,mmap()文件到内存的映射,open()打开一个文件,flush()关闭文件时减少f_count计数,release()释放文件对象,fsync()将文件在缓冲的数据写回磁盘。
1.3各个对象之间的关系
在顶层是打开的文件对象。
它由进程的文件描述符列表引用。
文件对象引用目录项对象,
后者引用索引节点对象。
这两个对象都引用底层的超级块对象。
多个文件对象可以引用同一个目录项对象。
一个目录项对象还可能引用另一个目录项对象。
下图展现了这样一个关系:
1.4VFS的工作方式
在VFS中,用户程序在进行文件操作时的过程是这样的:
首先调用open()函数来建立一个和具体文件的链接,这个链接首先是通过目录入口缓存(Dentrycache)将一个路径转换为特定的dentry的参数。
而dentry再通过指针和磁盘上的inode节点联系(在VFS中任何一个已经安装的文件都有自己的一个对应的Inode)。
从而确定要查找的文件。
为了快速查找文件。
Linux中采用两级缓冲机制。
一种是管理层面上的缓冲。
体现在文件目录项和记录文件名到文件的物理地址的对应关系。
另一层面的缓冲是软件层面的缓冲,主要是为了提高查找速度。
在VFS中,文件目录的访问是完全动态的,同一物理空间可以mount到不同的目录上。
此外,VFS的超级块是一个双向链表,它定义了一个文件的原型,使其他文件结构按要求组织到文件系统中。
Linux通过安装一个文件系统将该新文件系统加入到它的文件系统树中。
所有文件系统,不管是什么类型,都安装在文件系统树的一个目录上并且文件系统之上的文件将覆盖掉这个安装目录中原来存在的内容。
这个目录称之为安装目录或安装点,当文件系统被卸掉之后,安装目录的原有文件才再次可见。
每一个安装了的文件系统都被一个VFSsuperblock所表示,在其信息之中,VFSsuperblock包含设备(DEVICE),这是此文件系统所依赖的块设备的设备标识符。
例如,/devhad1,系统中的IDE硬盘有一个标识符0x301,inode指针mountedinode指针指向这个文件系统的inode。
所有的Linux文件系统使用相同的缓冲区缓存(buffercache)机制来缓冲来自底层的数据,这个机制使得文件系统对物理数据存储设备的存取得到加快。
这个缓冲区是独立于文件系统的,被集成入Linux核心机制中用来分配和读写缓冲区。
这个机制的最大特点是它的Linux文件系统独立于底层的物理介质,独立于设备的驱动程序。
当真实的文件系统要从底层物理设备读取数据时,其结果是触发一个块设备驱动程序向他们控制的设备发出读物理块的请求,集成在设备接口里的就是缓冲区缓存。
当文件系统读入数据块以后,它们被存放在这个全局的缓冲区缓存中,被文件系统和Linux核心所共享。
在其内的缓冲区数据通过块号码和对应于其设备的标识符被系统唯一标识。
因此,如果同样的数据经常需要被使用数据将从缓冲区缓存被检索而非从磁盘读入。
1.5VFS的结构优点
Linux的VFS系统的优点概括起来有以下几点:
1)从VFS的总体结构上来说,采用这样的机制可以为用户提供一个良好的使用不同文件系统的操作界面;
2)VFS中的dentry和inode的机制使LINUX更便于管理文件;
3)在dentry中,VFS采用双文件名的方法使文件名的使用更加灵活;
4)VFS中的cache机制更好地解决系统和外部设备之间的匹配问题和实现文件的快速查找;
5)VFS中的构链机制比较灵活;
6)Linux的VFS系统中的超级块和其他一些数据结构的构造非常好。
2VDBMS
2.1虚拟数据库(VDB)的体系结构
2.1.1数据集成系统
数据集成系统的功能主要是,从各种数据源处收集数据并且给上层应用提供一个单一的,一致的关系数据库接口。
这一复杂工作由3个功能模块完成。
(1)包裹器:
包裹器与数据源打交道并是分散数据成为一些表的集合,通常,它分析Web上的HTML,KHTML,XML或SMIL语言,并把他们表示成关系数据源。
包裹器是用源描述语言SDL(SourceDescriptionLanguage)来表现原始数据源的,此种语言是Junglee公司发明的位置描述语言,它用来描述数据源的行为。
简单的SDL语句可以捕获大多数复杂Web站点的结构,包括哪些页面时动态生成的站点。
此外,它同样可在超连接的页面之间捕获关系,并把这些关系体现在虚拟数据库的表中。
(2)映射器:
包裹器所形成的关系数据表可能具有不同的模式和词汇。
映射器可做属性名称和单位格式的转换,这些转换需求体现为映射规则的集合,并且用映射描述语言MDL(MapDescriptionLanguage)字义。
MDL可简明地描述非常强大的数据转换方式,包括模式和词汇转换,从一些表中把数据集成起来,基于其他的字段创建表的新字段以及简化数据和格式化形式等等。
(3)提取器:
数据集成系统常常涉及到从非结构的文本数据中提取结构化数据的操作。
然而,这些数据都分散在文本中,由此需要一种提取结构化数据的方法。
提取规则就描述怎样从文本中提取所需信息,用提取额描述语言EDL(ExtractDescriptionLanguage)描述的提取规则,具有强大的文本处理和语言分析能力。
2.1.2数据发布系统
如果说数据集成是VDB系统的心脏,则数据发布系统就是它的大脑。
发布器使用发布规则安排数据的获取转换盒传播。
为了使集成数据表IDT(IntegratedDataTable)能够以每日或每周的间隔发布出去,发布器要安排不同的数据集成工作。
IDT是数据源经过数据集成系统集成后的快照,包括关系数据表和图片之类的多媒体对象。
IDT可在VDB系统中传播,也可在Internet上传播。
数据发布系统有以下特征:
(1)可伸缩的工作安排功能:
数据发布系统支持一些一般的任务,这些任务包括:
查询包裹器,使用映射规则
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 虚拟 文件系统 VFS 数据库 管理 系统 VDBMS