首页 > 代码库 > 硬盘信息

硬盘信息

  机械一个盘的最小物理单位是扇区,扇区就是柱面和从圆心向外发射线切割而成的最小块,大小为512byte,如此一来一个硬盘分区就将有无数个删除,对于数据量太大,操作系统无法基于扇区寻址(数量太多了),因为存储数据指针的空间长度有限,存不下这么多扇区长度,于是操作系统就将相邻的若干个扇区归结在一起,形成所谓的“簇”,如此一来,就有若干个“簇”,“簇”的个数等于扇区总数除以每个“簇”所占的扇区。对于windows文件系统而言,一般一个“簇”会占用2、4、8、16、32或64个扇区,操作系统就是基于“簇”来进行寻址。比如我的电脑文件系统为NTFS,“簇”的大小是4k,所以每个“簇”就占用了8个扇区。有时候我们也把“簇”叫做数据块。一个文件如果小于4k,那么他将占用一个“簇”,如果大于4k他将占用若干个数据块。这也就是为什么,在电脑上面新建一个txt文件,里面只存两个字他也要占用4k的原因。

  操作系统每次读取一个或者多个数据块。每个块只能存放一个文档数据,Linux亦是如此。

  操作系统的块是操作系统的块,Oracle的块是Oracle的块,二者不能混为一谈,但是二者是相关联的。

  对于数据库,Oracle,由于我才疏学浅,只是对Oracle相对较熟悉,SqlServer和MySql不是很熟悉,所以仅仅针对Oracle来说。不过其他的数据库大致原理我想应该也差不多。我们平常说所的Oracle数据块,他是占用了N倍操作系统的数据块,N是偶数(1除外),Oracle的数据块大小可以是4k,8k,16k,32k,64k,也就是那个db_block_size的值,通过select value from v$parameter where name=‘db_block_size‘语句可以查询出来(需要DBA权限才能看到),我机器上是8k,也是Oracle的默认块大小,既然是8k,就是操作系统“簇”的2倍,这样做的用意何在?这就得从数据查询的角度来看,Oracle每一次读取最少一块,数据没沾满一块也要读取一块,这个操作系统的读取都一样。我们都知道查询分为2中,一种是全表扫描的方式,把整张表的数据全部读取,这样就为了减少IO次数,就需要块越大越好,另外一种是索引查询,因为索引查询IO次数非常少,我们希望每次读取的块大小跟操作系统的块大小一样就够了(排除海量数据,海量数据需要表分区,同时块也不能太小,太小索引B树层次太多),这样就很矛盾,对于不同的情况,有时候希望大些,有时候希望小些,所以折中8k比较合适。

  题外话,数据库块也称作数据库“页”。比如平常对MySql所谓得表锁,行锁,页锁,这个页锁的页就是数据库块。Oracle没有页锁这个概念。只有表锁和行锁,并且Oracle的行锁跟MySql还不太一样,Oracle的行锁开销其实相当小。不像MySql行锁开销很大,竞争很大,死锁也很多。这也能说明Oracle技术强大的原因。

  上面的情况是针对一般的情况而言,但是对于不同用途的表,我们需要建立不同块大小的表。通俗点来说,我们平常的CRUD表就因为经常变动,也经常通过索引查询,所以需要块小一点,而对于仓库表,用来做数据分析,统计的仓库表(通常是全表扫描),用作日志的表(通常不停的往表里面写数据,一般不用查询),这种类型的表就需要块比较大,毕竟越大,IO次数越少。也也就是所谓的数据库优化的一个方面。比较专业的说法是这两种类型的表称作:OLAP和OLTP。

  上面将操作系统和Oracle数据库的块分别解释了一下,接下来继续说操作系统的块。操作系统的块按照起存放的数据不同其实又分为2种,一种是索引块,一种是数据块,此针对NTFS和Linux的Ext2这些文件系统。他将文件属性和权限(比如Linux有rwx权限,拥有者,群组,时间参数等)和数据分别存放在索引块和数据块,名字叫做inode block与data block中,inode存放有data block的地址。通过找到inode来对data block寻址,速度快,并且如果data block不连续,也能够一次性读取出不连续的块的内容,这也就是为什么NTFS和Ext2这种文件系统整理碎片之后和之前效果差不多,FAT不一样,FAT就需要整理碎片,因为他不是通过索引来读取数据的,有点类似链表结构。其实说操作系统文件系统有2种块还不够全面,分区开头还有一种超级块super block,存放整个分区的信息,比如用量,剩余量,扇区数量等等。分别称这3种类型为inode,block,super。并且inode和block大小是不一样的,在Linux下面inode是128byte,而block可以划分成1k,2k,4k这几种类型,super是1024bytes,当然看情况划分,分的太小,对于大文件inode会存在读取性能问题,分的太大,对于很多小文件造成对空间的浪费。这里的inode其实才用的多级处理方式来记录文件所占块编号的。这个super并不是磁盘开头的MBR区域。MBR区域是存放整个磁盘的信息的,super只是存当前分区信息的。MBR(Master boot record)主引导记录,一般是512byte,而这个区域可以分为两个部分。第一部分为pre-boot区(预启动区),占446字节;第二部分是Partition table区(分区表),占66个字节,该区相当于一个小程序,作用是判断哪个分区被标记为活动分区,然后去读取那个分区的启动区,并运行该区中的代码。他是不属于任何一个操作系统,也不能用操作系统提供的磁盘操作命令来读取它。但我们可以用ROM-BIOS中提供的INT13H的2号功能来读出该扇区的内容,也可用软件工具Norton8.0中的DISKEDIT.EXE来读取。对于文件太大的情况,存放在磁盘上是相当分散的,虽然说索引技术可以一次性读取出来的,但是由于在硬盘上分散的太过于散开,机械手臂移动幅度会很大,那么也会影响读取性能。

  每个文档或者目录都会占用一个inode,用来记录文件或者目录所占的所有块地址。前面说了inode是通过分级存放数据块编号(说地址不准确)的。

  再说数据库索引,我们所谓的通过索引找到索引结构的根,再一层一层往下找到数据,那怎么找到根的呢,其实就是通过文件系统索引块来找到跟块,然后跟块再一层一层往下找。跟块就不用在通过索引来找下一个节点块,因为没必要,跟块里面直接存放了下层节点的地址。