开源中文网

您的位置: 首页 > 数据库应用 > Oracle > 正文

db_block_size是操作系统块的原因?

来源:  作者:

请问 

所有资料上都说 
db_block_size 要配置成操作系统块的整数倍 
能够提高 处理速度, 
可是都没有说明原因?那位老大能说明一下原因啊?:em14: 

ivhb 
oracle可以用裸设备。但是用裸设备也要用操作系统自己的打开/读写设备的接口。 
在unix下,就是open/read/write。对于块设备,unix一般每次读写512字节,这就是unix上的块大小。 
简而言之,oracle可以绕过文件系统(用操作文件系统--也就是熟文件,那么打开文件时候,操作系统会给你在操作系统层级上进行缓存。相当于访问数据时候 磁盘->操作系统文件块缓存->数据库缓存->检索到返回用户)。如果用裸设备的,则不会有操作系统缓存这一块。少了一次复制吧。 

简要来说: oracle可以绕过文件系统,但是不可能绕过系统调用。 
只要运行在操作系统上,要访问设备或者内核数据,都必须通过系统调用,切换程序运行态为核心态,才可能做到。 

至于说的必须是整数倍,也就好理解了。 
因为系统的块大小是一次读写的基本单位。假定块大小是512字节,DB_BLOCK_SIZE配置成600,那么每读取数据库的一块,操作系统层面需要发生两次读,才能完整的读取到数据库的块。其中,第二次读写只有88字节是有效的。相当于浪费了一部分读取能力 

[[i] 本帖最后由 ivhb 于 2008-9-8 23:00 编辑 [/i]] 
ILoveMK 
:mrgreen: good 
jayli426 
那下面理解是否正确,大虾执教啊 
1)对于裸设备?db_block_size配的越大越好,或者说尽量配大?是否配成8192,每次读取就是取8192,而不是512?(感觉好像理解错了,但是不知大虾专门提到裸设备的目的是为何) 
2)对于文件系统,配成8192和配成512其实不能提高多少速度,因为配成8192还是需要读16次,只是一回读的块数多了,但是对于IO而言,每次读的字节数没有增加啊,该读多少还是多少。仅仅是配成非整数倍的时候有些浪费? 
doni 
db_block_size的设置与数据库应用面有关,也就是说这个库的数据是怎么样的,读写时又是怎么样的 

在特定条件下,db_block_size对性能有相当的影响,我做过一些测试, 
在Solaris 8 + oracle 7 或 Solaris 10 + oracle 7的条件下,在多个机型上做imp 
db_block_size 设置为8192比2048的imp速度可以提高近50% 
jayli426 
大虾,你这是实践证明。 
但不是理论说明啊,只是让大家多了一个经验,却没有理论总结 
能否在原理上阐述一下 
doni 
比如:你打完麻将,打牌放回盒子,是一个个放快呢,还是4个4个放快呢? 
当然也是不每次的数量越大越好,要看你的手有多大。 

所以db_block_size的设置要根据具体情况来定 
camham 
block size就是数据库与磁盘一次交互的大小,或者说是io。如果每次操作都需要大量数据返回,则block越大越好,效率高。反之,如果只是做单条记录操作,例如insert,再大block都一样,反而浪费了内存。具体大小要看效率,简单説业务系统用小block,分析系统用大block 
jayli426 
因为小弟非科班出身,操作系统不熟悉 
请问:数据库与磁盘一次交互要怎么理解 
同一次IO是什么关系 

例如现在磁盘IO一次读取的大小是512bytes 
那么8192bytes就总需要读16次 
而不论你的db_block_size是多少 
例如db_block_size=8192,需要16次IO读取 
例如db_block_size=8192/2 ,但是读8912还是需要16次读取 

即:反正IO的读取次数是不会变的哦 

借用这个比方“比如:你打完麻将,打牌放回盒子,是一个个放快呢,还是4个4个放快呢?” 
目前我的理解层面上就不会出现“4个4个放快呢?”的情况啊 

那么这时理解“数据库与磁盘一次交互” 
就很重要了, 
原谅小弟的菜蔬学浅啊 
原谅小弟的反反复复,罗罗所所啊:em14: 
ivhb 
没错,db_block_size是设置多大,最后产生的物理的IO的次数也会随之变化。 
这个没有疑问的。比如DB_BLOCK_SIZE设定为4K和32K,那么,前者大概发生8次读操作;后者发生64次读操作。 

OLAP一般推荐使用较大的db_block_size,而OLTP一般推荐使用较小的db_block_size。 
原因在于,数据库读取一条记录(注意是一条记录也好,多条记录也好。都是一样的) 
数据库系统都会按照你的要求去定位记录,如果该记录在缓存中,则从缓存中直接读取。如果该记录不再缓存中,则从定位到磁盘块,然后读取---注意,是读取一整块(db_block_size大小),缓存到sga中。这个缓存动作以db_block_size为单位的。 

这样,你可以发现,对于OLPT来说,一般都是输入一个客户号,一个帐号。。。根据这些信息一般都能唯一的定位到一条记录,然后操作该记录,是一个很典型的scattered read动作(记录很分散)。记录访问的分散造成的后果是---你的内存大小是固定的,数据库不可能总是帮你缓存所有的记录。因此,经常发生缓存和磁盘的交换(显然的,db_block_size设定越大,记录访问越随机越分散,则发生交换的次数越多---意味着更多的读写磁盘发生。这样就会显著的降低系统的效率)。 
对于OLAP来说,一般都是会操作所有的记录。记录的访问具有连续性。你可以发现,一次缓存越多,基本上来说就是越有利。 

db_block_size本质上来说,就是给了用户预读数据,下次访问从缓存中读取/更新,而不是每次从磁盘上读取,而带来的性能上的提升。db_block_size设定越大,在一定程度上,造成的内存浪费越大(在随机访问下尤其如此)。如果内存是无限的,我想不管是OLAP或者OLTP来说,都会推荐大的db_block_size---也许就没有了db_block_size---整个数据库的全部数据都在内存 


这是之前在ChinaUnix论坛的上的一个提问,chinaunix就是这点不好,一旦没有置为精华,过一段时间就会被清除掉,想找都不找不到,幸好有位有心人,保存了这个帖子,所以我又从他那里copy回来 

这个应当说明了DB_BLOCK_SIZE的原因,照大虾的 回答,DB_BLOCK_SIZE 是操作系统的整数倍的意义并不大,关键是DB_BLOCK_SIZE 是为了在内存中命中率,对于OLTP系统,因为记录访问随机和分散,所以DB_BLOCK_SIZE设得相对较小就有好处 

什么意思呢,假设我们的DB_BUFFER只有 32k大 

如果我们要经常更新32条记录,他们每条记录至少差8k的距离 

什么意思,就是每8k才有一条记录, 

那么如果DB_BLOCK_SIZE=8k,那么DB_BUFFER实际上只放了4条我们常做更新的记录 

但是如果DB_BLOCK_SIZE=1k,那么DB_BUFFER实际上就能放了32条我们常做更新的记录 

但是对于OLAP,我们通常需要对大量数据做统计,数据一般是连续性的,所以 

这个时候DB_BLOCK_SIZE大一些就更好吗? 

Tags:dbblocksize 操作系统
关于开源中文网 - 联系我们 - 广告服务 - 网站地图 - 版权声明