可能是一个多月前看到小无赖提出的两个问题,最近抽空试了一下。
原问题如下:
一个对象是否只有一个对象分配页OAM?
http://chinaunix.net/forum/viewtopic.php?t=65106&highlight=OAM
一个OAM能存储多少个分配单元的信息?
http://chinaunix.net/forum/viewtopic.php?t=82826&highlight=OAM
我在solaris上建立了一个数据库test,4G data, 1G log, 并建立了一个表test,
经过一整夜的疯狂插入,最终的结果如下:
sp_spaceused test
name rowtotal reserved data
index_size unused
-------------------- ----------- --------------- ---------------
--------------- ---------------
test 300719376 4176724 KB 4176658 KB
0 KB 66 KB
首先可以回答第一个问题,表并没有2G的限制,只要设备足够大,表就可以足够大。
通过dbcc listoam("test", 32000114, 0)
得到以下的输出:
-----------------------------------------------------------------------------
Objid: 32000114 indid: 0
[color=red:49a6d2b4e5]OAM pg cnt: 33 [/color:49a6d2b4e5] Entry cnt: 8190
Rows: 300719376 Rows Per pg: 144
Used pgs: 2088362 Unused pgs: 0
Attribute entries: 10
OAM status bits set: (0x8000 (PG_OAMPG), 0x0008 (PG_OAMATTRIB))
LAST SCANNED OAM PAGE: 0
ALLOCATION HINTS :
513 56833 120833 184833
248833 312833 376833 440833
504833 568833 632833 696833
760833 824833 888833
IDENTITY Max burned value from disk: NULL From the DES: NULL
OAM pg # 513 has the following 240 entries (allocpg:used/unused
512:167/ 0 768:255/ 0 1024:255/ 0 1280:255/ 0
1536:255/ 0 1792:255/ 0 2048:255/ 0 2304:255/ 0
2560:255/ 0 2816:255/ 0 3072:255/ 0 3328:255/ 0
3584:255/ 0 3840:255/ 0 4096:255/ 0 4352:255/ 0
4608:255/ 0 4864:255/ 0 5120:255/ 0 5376:255/ 0
5632:255/ 0 5888:255/ 0 6144:255/ 0 6400:255/ 0
6656:255/ 0 6912:255/ 0 7168:255/ 0 7424:255/ 0
7680:255/ 0 7936:255/ 0 8192:255/ 0 8448:255/ 0
8704:255/ 0 8960:255/ 0 9216:255/ 0 9472:255/ 0
9728:255/ 0 9984:255/ 0 10240:255/ 0 10496:255/ 0
。。。。。。
显然,他有33个OAM page。
所以,一个对象可以有多个OAM page。
那么,一个OAM能存储多少个分配单元的信息(小无赖的提法)?或者说,一个OAM page可以管理多大的数据空间呢?
其实,小无赖的这个提法是对的,一个OAM页中存放的纪录称为OAM entry。一个entry为8个字节,包括AU(Allocation unit)的地址,AU中分配的页面数/未分配的页面数.
我的表的大小为4176658 k(由以上的sp_spaceused输出得到),又有33个OAM page。
因此,一个OAM page可以管理的数据空间大约为:
CapacityManagedByOneOAMPage =
4176658 k / 33 = 123.6 M
也就是说,当表的空间大于123.6M时,就需要新的OAM page了
实际上,这个估算是比较准确的,OAM page 是以双向循环链表的方式连接在一起的,第一个OAM page可以存放240个 OAM entry, 余下的OAM page可以存放250个 OAM entry. 就以250为准。
CapacityManagedByOneOAMPage =
250 *
NumberOfDataPagesInAllocationUnit *
LogicalPageSize / 1024(M)
这里NumberOfDataPagesInAllocationUnit为255而非256,是因为AU中的第一页为allocation page。不计在内
LogicalPageSize就以2K代入吧,我的@@pagesize = 2k
结果等于
CapacityManagedByOneOAMPage =
250 *
255 *
2 / 1024 = 124.5M
与前面估算的差不多吧
还有一个有趣的现象,在sp_spaceused中
unused = 66kb,正好是33个OAM page 占用的空间
不知道讲明白了没,希望对大家又帮助
jazy 回复于:2003-07-16 19:23:53
很好,欢迎大家能这样深入的讨论问题!
joey 回复于:2003-07-17 09:02:06
早知道换图标就可以得精华,早就换了。
zhangyh123 回复于:2003-07-17 10:06:14
首先对楼主的实验精神表示敬佩!
我想说说我的一点看法。
1、 OAM 页建立在逻辑页的基础上,如果逻辑页为 8K 那么
里面包含的条目应该比 逻辑页为2K 的条目多。那么,一个 OAM 所指向的含有该对象的页单元的指针的数量可能就不一样多了。
2、在一个数据库有若干表,并且都有多种操作, 如 insert delete update
等的情况下,表的空间分配肯定不是连续的,因此,同样的数据量,比如 100M,该表所跨越的含有该对象的页单元的数量就不是确定的,这样 OAM 也就不是确定的,只能说在一种特定的情况下达到一种特定的结果。
综合以上所叙述,讨论一个表有多少 OAM 或者 1个 OAM 能够管理多少数据的
说法就值得怀疑。我想,如果有这样的一种固定关系,在 sybase 的说明文档中可能就会明确写出。
另外,从sybase 数据库的数据分配与存储机制上讲,OAM 与数据量没有一个线性关系的含义,只是一种数据加速分配与读取的机制,即使没有 OAM 数据库一样可以使用,但可能会慢很多。
这个是我个人的看法,希望能够与大家讨论!
数据库表的大小受到操作系统的限制, sybase 数据库表在 device 与实际表中间有一个 segment 的概念,数据库表不是建立在 device 上,而是在 segment 上,这样,就大大扩展的数据容量。跟 oracle 的表空间/数据文件是一样的道理。
Z2Y3 回复于:2003-07-17 10:15:35
顶.
joey 回复于:2003-07-17 13:14:41
sorry, 问中有一处小错误。
确定当前的logical page size, 应使用@@maxpagesize。
而非@@pagesize
@@pagesize恒为2048
心影 回复于:2003-07-17 19:49:29
小无赖?是谁啊?好可爱的ID啊!
常笑 回复于:2003-07-17 21:09:56
[quote="zhangyh123"]首先对楼主的实验精神表示敬佩!
我想说说我的一点看法。
1、 OAM 页建立在逻辑页的基础上,如果逻辑页为 8K 那么
里面包含的条目应该比 逻辑页为2K 的条目多。那么,一个 OAM 所指向的含有该对象的页单元的指..........[/quote]
顶,当初我也参加过讨论!(汗,在一次对楼主的实验精神所折服!)
当初说小无赖的提法不对就是基于
表的分配空间不是连续的,该表所含有该对象的页单元的数量就不是确定的,这样 OAM 也就是不确定的了。
小无赖 回复于:2003-07-18 15:40:26
终于有人还喜欢我的ID,真不旺我煞费苦心想出来啊!
其实实验证得资料所说的一个OAM页可以管理2000-63750个页的事实嘛.2088362/33=63283大约没个OAM页平均管理63283个页,我想2000-63750有这么大的范围就是因为页大小的不同,如果是16k的话应该就只有2000多个.对了这个假设也可做个实验哦!
你们用的dbcc命令我怎么在手册上都查不到,都是在哪找出来的啊,望相告! 
Blackrose 回复于:2003-07-18 15:58:08
我也喜欢!
小无赖 回复于:2003-07-21 16:43:37
你们用的dbcc命令我怎么在手册上都查不到,都是在哪找出来的啊?
joey 回复于:2003-07-21 17:52:59
是sybase内部用的,不公开的。但在sybase论坛上可以找到很多。
li2002 回复于:2003-07-21 18:51:30
dbcc listoam("test", 32000114, 0)
命令中的32000114 是什么意思?如何得到的呀?
是select id from sysobjects where name='test'
得到的吗?
我怎么不能执行该语句呀?提示:
Msg 7964, Level 14, State 1:
Line 1:
Permission denied. Yo[1] [2] 下一页 |