ASM的文件管理深入解析.docx
《ASM的文件管理深入解析.docx》由会员分享,可在线阅读,更多相关《ASM的文件管理深入解析.docx(23页珍藏版)》请在冰豆网上搜索。
ASM的文件管理深入解析
ASM的文件管理深入解析
第一章 ASM文件
ASM中的文件总体上来说,分为两大类,元文件和数据文件。
数据文件包含Oracle的数据文件、控制文件、重做日志文件、归档日志文件等等。
对于ASM来说,只要是非元文件,就是数据文件。
每一个文件,在ASM中都有一个专门的索引号,也就是编号,ASM文件索引号从1开始。
其中,前255个,也就是1至255号文件,都是元文件。
256之后的是其他各种文件。
元文件中包含了各种ASM的配置、各类数据文件信息还有目录、别名等等信息,都是在元文件中的。
所有V$ASM_开头视图的信息,都来自元文件中。
其中,1号文件包含所有文件的磁盘占用信息,包括元文件、甚至1号文件自身的空间分布信息,也都是在1号文件内部。
每个文件在它里面占用一个块(4096字节,元数据块大小为4K)的空间。
从256号文件开始,是数据库的各类文件。
假设你放在ASM上的第一个文件是一个控制文件A,第二个文件是一个数据文件B。
那么控制文件A在ASM中的索引号是256,数据文件B的索引号是257。
1号文件总是开始在0号磁盘2号AU,记住这个位置:
0号盘2号AU。
这是ASM中定位文件的起点,它的作用,有点相当于磁盘上的引导区,在电脑开机后负责将OS启动起来。
1号文件在最少情况下,至少有两个AU。
上面我们提到过了,在1号文件中,每个文件占用一个元数据块,存放自身的空间分布信息。
每个元数据块大小是4K,一个AU是1M,那么,每个AU中,可以存储256个文件的空间分布信息。
这其中,0号盘2号AU中,全是元文件的信息。
再具体一点,0号盘2号AU,第一个元数据块被系统占用,从第二个块开始,到255为止,共255个元数据块,对应索引号1至255的文件。
其实,也就是全部的元文件了。
也就是说0号盘2号AU,保存了全部元文件的空间分布信息。
1号文件的第二个AU,从第一个块开始,保存256号文件。
第二个块对应257号文件,等等。
每次从ASM中读数据时,Oracle都要先读到1号文件,从中找出要读的目标文件在磁盘上的分布位置,然后再去读取相应的文件的数据。
不用太多文字了,文字不是最直接的表达方式,还是换成图形吧。
2012-3-3109:
21上传
下载附件(50.02KB)
图1
这张图假设某一DiskGroup中有0到N个磁盘。
再看下图:
2012-3-3109:
21上传
下载附件(77.6KB)
图2
我们把0号盘,2号AU单独拿出来,放大显示。
0号盘2号AU,是1号文件第一个AU,共有256个元数据块,编号0至255,0号块留用。
1至255号块分别保存了1号文件自身和2、3等等直到255号文件的AU分布信息。
那下面,如果我想知道某一个文件的AU分布,如何查看呢?
第二章 kfed
1、链接kfed
查看ASM磁盘的信息,可以使用KFED,在非Windows操作系统下,kfed已经编译过了,只要链接一下,就可以使用了,步骤如下:
(1)、找到ins_rdbms.mk所在路径,并进入。
此步骤不再列出。
(2)、执行如下命令,即可链接kfed。
make-fins_rdbms.mkikfed
2、在ASM中确定磁盘:
SQL>selectgroup_number,namefromv$asm_diskgroup;
GROUP_NUMBERNAME
------------------------------------------
1DG1
我目前只有一个DG,名字是DG1,GROUP_NUMBER为1。
SQL>selectgroup_number,disk_number,pathfromv$asm_disk;
GROUP_NUMBERDISK_NUMBERPATH
-------------------------------------------
1 0ORCL:
VOL1
1 1ORCL:
VOL2
目前,我DG中,有两个磁盘。
但这两个磁盘分别是谁,从ASM的视图中,还看不出来。
不过,可以分析一下得出,/dev/sda这个盘,是系统留用的,sdb、sdc很有可能是ASM的VOL1、VOL2。
那么,如何确认一下呢?
这里,我也没有什么好方法,我们这样:
[root@red1dev]#ddif=/dev/sdbbs=1count=45|hexdump-c|more
45+0recordsin
45+0recordsout
0000000001202001001 \0 \0 \0 \0 \0 \0 \0200 , , m
0000010 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 O R C L D I S K V O L 1 \0
000002d
我dd命令,将/dev/sdb的前45个字节输出,其中,我们可以看到O R C L D I S K V O L 1。
那么,/dev/sdb就对应VOL1了。
使用同样的方法,可以确定sdc是VOL2。
还可以确定,磁盘没有分区:
[root@red1dev]#ddif=/dev/sdb1bs=1count=45|hexdump-c
dd:
opening`/dev/sdb1':
Nosuchfileordirectory
不存在/dev/sdb1这样的设备。
这种确定方法确实麻烦了一些,大家如果知道有什么简单方法可以补充。
好,我们已经确定,/dev/sdb对应VOL1,是磁盘0,/dev/sdc对应VOL2,是磁盘1。
在我们使用kfed时,还用不到这个,如果用程序直接读取ASM文件的话,就需要用到这个信息了。
3、使用Kfed
我们使用Kfed直接读取0号磁盘,2号AU,1号元数据块吧。
0号元数据块是1号文件自身留作文件头的。
1号元数据块呢,是1号文件的AU分布,2号元数据块,是2号文件的AU分布。
等等。
下面,我们用Kfed读取下1号元数据块。
[oracle@red1disks]$kfedread/dev/oracleasm/disks/VOL1aun=2blkn=1|more
kfbh.endian:
1;0x000:
0x01
kfbh.hard:
130;0x001:
0x82
kfbh.type:
4;0x002:
KFBTYP_FILEDIR
kfbh.datfmt:
1;0x003:
0x01
kfbh.block.blk:
1;0x004:
T=0NUMB=0x1
kfbh.block.obj:
1;0x008:
TYPE=0x0NUMB=0x1
kfbh.check:
4143342569;0x00c:
0xf6f663e9
kfbh.fcn.base:
268;0x010:
0x0000010c
kfbh.fcn.wrap:
0;0x014:
0x00000000
…………………………………………………………………………
等等
Kfed可以帮我们列出很多信息,有了这些,ASM的大部分秘密将被揭开。
kfed的信息是这样看的,比如:
kfbh.endian:
1;0x000:
0x01
kfbh.endian是C语言的结构(struct)中的域。
1;0x000:
0x01:
kfbh.endian的十进值为1,0x000是指它开始自第0个字节处,最后的0x01是十六进制值形式。
此域的意义是主机的大小端。
0是大端,1是小端。
此处值为1,说明主机是小端。
其他的这里就不再一一列出了,对其中的每个域,我后面有详细的说明。
下面,只说相关的,在Kfed中找到如下信息:
kfffde[0].xptr.au:
2;0x4a0:
0x00000002
kfffde[0].xptr.disk:
0;0x4a4:
0x0000
kfffde[0].xptr.flags:
0;0x4a6:
L=0E=0D=0C=0S=0
kfffde[0].xptr.chk:
40;0x4a7:
0x28
kfffde[1].xptr.au:
27;0x4a8:
0x0000001b
kfffde[1].xptr.disk:
0;0x4ac:
0x0000
kfffde[1].xptr.flags:
0;0x4ae:
L=0E=0D=0C=0S=0
kfffde[1].xptr.chk:
49;0x4af:
0x31
kfffde[2].xptr.au:
4294967295;0x4b0:
0xffffffff
kfffde[2].xptr.disk:
65535;0x4b4:
0xffff
kfffde[2].xptr.flags:
0;0x4b6:
L=0E=0D=0C=0S=0
kfffde[2].xptr.chk:
42;0x4b7:
0x2a
kfffde[3].xptr.au:
4294967295;0x4b8:
0xffffffff
kfffde[3].xptr.disk:
65535;0x4bc:
0xffff
kfffde[3].xptr.flags:
0;0x4be:
L=0E=0D=0C=0S=0
kfffde[3].xptr.chk:
42;0x4bf:
0x2a
………………
如果你对C语言熟一点,我们会更容易描述这段信息,如果不太熟又想深入了解,可以回去翻翻谭浩强C语言书中结构体哪一部分,很简单的。
kfffde,是结构数组。
kfffde[0]的数据元素,存放了1号文件第一个AU的位置。
kfffde[1]存放了1号文件第二个AU位置,等等,依次类推。
我们来看一下上面的信息:
kfffde[0].xptr.au:
2;0x4a0:
0x00000002 :
2号AU
kfffde[0].xptr.disk:
0;0x4a4:
0x0000 :
0号磁盘
:
上两个信息合起来,0号盘2号AU,这就是1号文件第一个AU的位置
kfffde[0].xptr.flags:
0;0x4a6:
L=0E=0D=0C=0S=0:
标志位
kfffde[0].xptr.chk:
40;0x4a7:
0x28 :
校验码
通过上面kfffde[0]中的信息,我们可以知道,1号文件的第一个AU,位置在0号盘2号AU处。
再看kfffde[1],它对应1号文件第二个AU,位置在0号盘27号AU。
再往下看kfffde[3],AU编号4294967295,磁盘编号65535。
这说明1号文件还没有第三个AU。
通过上面的信息,我们可以得到,1号文件共有两个AU,分别在0号盘2号AU、0号盘27号AU。
再来一张图,帮助理解:
2012-3-3109:
21上传
下载附件(75.76KB)
图3
4、读取其他文件:
读取元文件
再来一个例子,假设我们想要访问3号文件,如何找出3号文件的AU都在哪里分布呢?
根据我们刚才所讲的,3号文件的AU分布,在(0号盘,2号AU,3号块)中,使用Kfed读取它:
[oracle@red1disks]$kfedread/dev/oracleasm/disks/VOL1aun=2blkn=3|more
…………………………
kfffde[0].xptr.au:
3;0x4a0:
0x00000003
kfffde[0].xptr.disk:
1;0x4a4:
0x0001
kfffde[0].xptr.flags:
0;0x4a6:
L=0E=0D=0C=0S=0
kfffde[0].xptr.chk:
40;0x4a7:
0x28
kfffde[1].xptr.au:
3;0x4a8:
0x00000003
kfffde[1].xptr.disk:
0;0x4ac:
0x0000
kfffde[1].xptr.flags:
0;0x4ae:
L=0E=0D=0C=0S=0
kfffde[1].xptr.chk:
41;0x4af:
0x29
kfffde[2].xptr.au:
4;0x4b0:
0x00000004
kfffde[2].xptr.disk:
1;0x4b4:
0x0001
kfffde[2].xptr.flags:
0;0x4b6:
L=0E=0D=0C=0S=0
kfffde[2].xptr.chk:
47;0x4b7:
0x2f
kfffde[3].xptr.au:
4;0x4b8:
0x00000004
kfffde[3].xptr.disk:
0;0x4bc:
0x0000
kfffde[3].xptr.flags:
0;0x4be:
L=0E=0D=0C=0S=0
kfffde[3].xptr.chk:
46;0x4bf:
0x2e
………………………………………………
根据我们前面我讲的,解读这些信息是很容易的。
3号文件的AU有:
(1号盘3号AU)、(0号盘3号AU)、(1号盘4号AU)、(0号盘4号AU)、…………。
还是来看张图吧,更加清楚些:
2012-3-3109:
22上传
下载附件(83.37KB)
图4
5、读取数据文件
我先在ASM中新建一个数据文件,然后,我们再来查看它的AU分布。
创建如下表空间:
createtablespacetbs_tst01datafile'+DG1/data/tbs_tst01_00.dbf'size10Mautoextendoff;
我们创建了一个10M大的数据文件,也就是说,它会有10个AU。
如下查询一下它在ASM中的文件索引号:
(在ASM实例中执行如下语句:
)
SQL>selectname,file_numberfromv$asm_aliaswherenamelike'tbs_tst01%';
NAME FILE_NUMBER
-----------------------------------------------------------
tbs_tst01_00.dbf 257
FILE_NUMBER列也是文件号,我们一般称它为ASM文件索引号,在这里tbs_tst01_00.dbf的索引号是257。
1号文件的第一个AU(0号盘2号AU)中,只能保存1至255号文件的。
从256号文件开始,AU的分布信息保存在1号文件第二个AU中,也就是(0号盘,27号AU)。
其中第一个块(0号块),对应256号文件。
1号块对应257号文件,等等,依此类推。
照惯例,我们先用Kfed读取一下0号盘27号AU的1号块,查看一下257号文件的AU分布:
[oracle@red1disks]$kfedread/dev/oracleasm/disks/VOL1aun=27blkn=1|more
…………………………………………
kfffde[0].xptr.au:
278;0x4a0:
0x00000116
kfffde[0].xptr.disk:
0;0x4a4:
0x0000
kfffde[0].xptr.flags:
0;0x4a6:
L=0E=0D=0C=0S=0
kfffde[0].xptr.chk:
61;0x4a7:
0x3d
kfffde[1].xptr.au:
277;0x4a8:
0x00000115
kfffde[1].xptr.disk:
1;0x4ac:
0x0001
kfffde[1].xptr.flags:
0;0x4ae:
L=0E=0D=0C=0S=0
kfffde[1].xptr.chk:
63;0x4af:
0x3f
kfffde[2].xptr.au:
279;0x4b0:
0x00000117
kfffde[2].xptr.disk:
0;0x4b4:
0x0000
kfffde[2].xptr.flags:
0;0x4b6:
L=0E=0D=0C=0S=0
kfffde[2].xptr.chk:
60;0x4b7:
0x3c
…………………………………………
…………………………………………
…………………………………………
kfffde[10].xptr.au:
283;0x4f0:
0x0000011b
kfffde[10].xptr.disk:
0;0x4f4:
0x0000
kfffde[10].xptr.flags:
0;0x4f6:
L=0E=0D=0C=0S=0
kfffde[10].xptr.chk:
48;0x4f7:
0x30
kfffde[11].xptr.au:
4294967295;0x4f8:
0xffffffff
kfffde[11].xptr.disk:
65535;0x4fc:
0xffff
kfffde[11].xptr.flags:
0;0x4fe:
L=0E=0D=0C=0S=0
kfffde[11].xptr.chk:
42;0x4ff:
0x2a
257号文件一共10个AU,所以,kfffde[11]中的AU位置和磁盘位置是0xffffffff、0xffff。
但kfffde[10]还有是明确的值的。
257号文件的10号AU位置:
0号磁盘283号AU,这其实是257的第11个AU。
tbs_tst01表空间使用的是“系统管理区大小”,也就是说区大小有64K、1M、8M等多种选择。
但是无论区大小,每个ASM中的文件,比原大小总会多出一个AU。
就像这里的257号文件,原大小是10M,但实际是11M,共11个AU。
再来一张图吧,有图清楚些:
2012-3-3109:
22上传
下载附件(76.08KB)
图5
2012-3-3109:
22上传
下载附件(111.96KB)
图6
上面图5和图6,具体描述了在ASM中读取257号文件的步骤。
在这里,257号文件创建大小是10M,实际在ASM中大小为11M,共11个AU。
这11个AU的信息,都在0号盘、27号AU、1号块中。
假设有一个非常大的文件,AU数也非常多,一个块中存不完,Oracle是如何处理的呢?
下面,我们继续。
6、读取特别大的文件:
间接AU
创建一个稍大一点的数据文件,比如200M:
createtablespacetbs_tst02datafile'+DG1/data/tbs_tst02_00.dbf'size200Mautoextendoff;
根据我们前面所讲的,200M的数据文件,在ASM中实际将占用201M空间(201个AU)。
下面,我们查找一下此文件的AU分布。
首先在ASM中执行如下命令:
SQL>selectname,file_numberfromv$asm_aliaswherenamelike'tbs_tst02%';
NAME FILE_NUMBER
-----------------------------------------------------------
tbs_tst02_00.dbf 258
确定一下,tbs_tst02_00.dbf的文件号是258。
它的AU分布信息,应该在1号文件的第二个AU的第3个块(2号块)中,老规距,先用Kfed读取1号文件第二个AU第3个块,也就是0号盘、27号AU、2号块:
[oracle@red1disks]$kfedread/dev/oracleasm/disks/VOL1aun=27blkn=2|more
………………………………………………………