裸设备

fdsik,dd,cpio等指令就是绕过了文件系统直接操作裸设备。裸设备的写是直接写扇区的,因为还没有格式化过,所以还没有块的概念,属于device层。 裸设备可以用df -h查看。 1、裸设备定义: 一块没有分区的硬盘,称为原始设备(RAW DEVICE)或者是一个分区,但是没有用EXT3,OCFS等文件系统格式化,称为原始分区(RAW PARTITION)以上两者都是裸设备。 2、裸设备的绑定 有文件系统的分区是采用mount的方式挂载到某一个挂载点的(目录)而裸设备不能mount,只能绑定到/dev/raw/下的某一个设备名 比如/dev/raw/raw1 3、裸设备的绑定方法 修改/etc/sysconfig/rawdevices,添加以下内容,这里sdd1和sdd2是原始分区名或者原始设备(硬盘)名,raw1和raw2是/dev目录下的原始设备名,编号从raw1到raw255,也就是最多可以绑定255个裸设备。 /dev/raw/raw1 /dev/sdd1 /dev/raw/raw2 /dev/sdd2 然后修改裸设备的属主和访问权限 chown oracle:dba /dev/raw/raw1 chown oracle:dba /dev/raw/raw2 chmod 660 /dev/raw/raw1 chmod 660 /dev/raw/raw2 最后使得裸设备生效,并且在机器启动的时候就自动加载执行 /etc/init.d/rawdevices restart 使裸设备生效执行 /sbin/chkconfig rawdevices on 保证机器启动的时候裸设备能够加载,这一步很重要。 4、裸设备的读写 不能用cp等命令操作,写入内容用dd命令,可以参阅相关资料。 5、清空裸设备,相当于格式化啦bs是块的大小,block sizecount是块的数量,这两者相乘大于裸设备的容量即可。 dd if=/dev/zero of=/dev/raw/raw1 bs=8192 count=12800 dd if=/dev/zero of=/dev/raw/raw2 bs=8192 count=12800

简单分层理解

buffered io:普通文件操作,对性能、吞吐量没有特殊要求,由kernel通过page cache统一管理缓存,page cache的创建和回收由kernel控制。其默认是异步写,如果使用sync,则是同步写,保证该文件所有的脏页落盘后才返回(对于db transaction很重要,通过sync保证redo log落盘,从而保证一致性)。 mmap:对文件操作的吞吐量、性能有一定要求,且对内存使用不敏感,不要求实时落盘的情况下使用。mmap对比buffered io,可以减少一次从page cache -> user space的内存拷贝,大文件场景下能大幅度提升性能。同时mmap将把文件操作转换为内存操作,避免lseek。通过msync回写硬盘(此处只说IO相关的应用,抛开进程内存共享等应用)。 direct io:性能要求较高、内存使用率也要求较高的情况下使用。适合DB场景,DB会将数据缓存在自己的cache中,换入、换出算法由DB控制,因为DB比kernel更了解哪些数据应该换入换出,比如innodb的索引,要求常驻内存,对于redo log不需要重读读写,更不要page cache,直接写入磁盘就好。

direct I/O与RAW

O_DIRECT 和 RAW设备最根本的区别是O_DIRECT是基于文件系统的,也就是在应用层来看,其操作对象是文件句柄,内核和文件层来看,其操作是基于inode和数据块,这些概念都是和ext2/3的文件系统相关,写到磁盘上最终是ext3文件。

而RAW设备写是没有文件系统概念,操作的是扇区号,操作对象是扇区,写出来的东西不一定是ext3文件(如果按照ext3规则写就是ext3文件)。

一般基于O_DIRECT来设计优化自己的文件模块,是不满系统的cache和调度策略,自己在应用层实现这些,来制定自己特有的业务特色文件读写。但是写出来的东西是ext3文件,该磁盘卸下来,mount到其他任何linux系统上,都可以查看。

而基于RAW设备的设计系统,一般是不满现有ext3的诸多缺陷,设计自己的文件系统。自己设计文件布局和索引方式。举个极端例子:把整个磁盘做一个文件来写,不要索引。这样没有inode限制,没有文件大小限制,磁盘有多大,文件就能多大。这样的磁盘卸下来,mount到其他linux系统上,是无法识别其数据的。

两者都要通过驱动层读写;在系统引导启动,还处于实模式的时候,可以通过bios接口读写raw设备。

pagecache/dentries/inodes

It appears you are working with memory caching of directory structures. 当我们正在使用内存缓存目录结构时,

An inode in your context is a data structure that represents a file. A dentries is a data structure that represents a directory. 在这个上下文中的inode是表示文件的数据结构,而dentries是表示目录的数据结构。

These structures could be used to build a memory cache that represents the file structure on a disk. To get a directly listing, the OS could go to the dentries–if the directory is there–list its contents (a series of inodes). If not there, go to the disk and read it into memory so that it can be used again. 这些结构可用于构建表示磁盘上的文件结构的内存高速缓存。为了直接获得列表,操作系统可以去dentries那里(如果目录在那里的话)列出其内容(一系列inode)。如果没有,则会去磁盘上将其读入内存,以便它可以再次使用。

The page cache could contain any memory mappings to blocks on disk. That could conceivably be buffered I/O, memory mapped files, paged areas of executables–anything that the OS could hold in memory from a file. 页面缓存(page cache)可以包含磁盘块的任何内存映射。这可以是缓冲I/O,内存映射文件,可执行文件的分页区域——操作系统可以从文件保存在内存中的任何内容。

如何释放pagecache/dentries/inodes

1
2
3
4
5
6
To free pagecache:
# echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
# echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
# echo 3 > /proc/sys/vm/drop_caches

/proc/sys/vm/dirty_writeback_centisecs:flush检查的周期。单位为0.01秒,默认值500,即5秒。每次检查都会按照以下三个参数控制的逻辑来处理。 /proc/sys/vm/dirty_expire_centisecs:如果page cache中的页被标记为dirty的时间超过了这个值,就会被直接刷到磁盘。单位为0.01秒。默认值3000,即半分钟。 /proc/sys/vm/dirty_background_ratio:如果dirty page的总大小占空闲内存量的比例超过了该值,就会在后台调度flusher线程异步写磁盘,不会阻塞当前的write()操作。默认值为10%。 /proc/sys/vm/dirty_ratio:如果dirty page的总大小占总内存量的比例超过了该值,就会阻塞所有进程的write()操作,并且强制每个进程将自己的文件写入磁盘。默认值为20%。