ASM 翻译系列第三十一弹:了解ASM文件的空间分配
译者: 邱大龙
审核: 魏兴华
DBGeeK社区联合出品
How many allocation units per file
本文主要是对ASM文件的空间分配进行一些探讨和研究。
ASM空间分配的最小单位是AU,默认的AU size是1MB,但在Exadata下AU 的默认大小是4MB。
ASM文件的空间分配是以extent为单位,每一个extent是由一个或多个AU组成,在11.2版本,前20000个extent,每一个extent由1个AU组成,接下来的20000个extent,每一个由4个AU组成,再超出的extent,每一个由16个AU组成。这个特性被叫做可变extent。而在11.1版本,extent的增长则遵循的是1-8-64倍AU的方式。在版本10,可变extent这个特性还没出现,因此所有的extent的大小都是1个AU。
Bytes vs space
视图V$ASM_FILE中,有两列是关于空间分配的:BYTES 和 SPACE,它们的定义如下:
- BYTES - 文件的大小
- SPACE - 文件实际占用的ASM空间的大小
这两列的定义有一些细微的差异,但是这两列的数值差异可能是非常大的,下面我们就来实际的看一下,首先交代一下我的测试环境,ASM和DB的版本为11.2.0.3,使用ASMLIB方式管理的磁盘:
可以通过如下的查询来简单的了解我的环境中磁盘组data的基本情况,例如AU的大小,冗余的级别,我的数据文件大多都位于这个磁盘组中。
SQL> select NAME, GROUP_NUMBER, ALLOCATION_UNIT_SIZE/1024/1024 "AU size (MB)", TYPE
from V$ASM_DISKGROUP
where NAME='DATA';
NAME GROUP_NUMBER AU size (MB) TYPE
---------------- ------------ ------------ ------
DATA 1 1 NORMAL
现在创建一个小于60个extent的“小”文件和一个大于60个extent的“大”文件。
SQL> create tablespace T1 datafile '+DATA' size 10 M;
Tablespace created.
SQL> create tablespace T2 datafile '+DATA' size 100 M;
Tablespace created.
Get the ASM file numbers for those two files:
SQL> select NAME, round(BYTES/1024/1024) "MB" from V$DATAFILE;
NAME MB
------------------------------------------ ----------
...
+DATA/br/datafile/t1.272.818281717 10
+DATA/br/datafile/t2.271.818281741 100
“小"文件的ASM文件号是272,“大”文件的ASM文件号是271。
接着我们通过前面提到的V$ASM_FILE视图来获取这两个文件的空间占用信息:
SQL> select FILE_NUMBER, round(BYTES/1024/1024) "Bytes (AU)", round(SPACE/1024/1024) "Space (AUs)", REDUNDANCY
from V$ASM_FILE
where FILE_NUMBER in (271, 272) and GROUP_NUMBER=1;
FILE_NUMBER Bytes (AU) Space (AUs) REDUND
----------- ---------- ----------- ------
272 10 22 MIRROR
271 100 205 MIRROR
bytes字段显示了文件的实际大小,我们小文件的大小为10MB,因此占用了10个AU(AU的size为1MB),小文件实际占用的ASM空间有22个AU,其中10个AU是实际的数据文件,1个AU为文件头,由于文件是镜像的,因此文件真正占用的ASM空间为:(10+1)*2=22个AU。
对于“大”文件,bytes字段显示了文件的实际大小为100MB也就是100个AU,到现在为止一切推论都跟原理相符,但是接着我们发现大文件的ASM空间占用为205个AU,按照上面的计算应该有202个AU才正确,多出来的3个AU是如何来的?接下来我们就来一窥究竟。
ASM space
下面的查询(在ASM实例上运行)展示了ASM 271号文件extent的分布情况:
SQL> select XNUM_KFFXP "Virtual extent", PXN_KFFXP "Physical extent", DISK_KFFXP "Disk number", AU_KFFXP "AU number"
from X$KFFXP
where GROUP_KFFXP=1 and NUMBER_KFFXP=271
order by 1,2;
Virtual extent Physical extent Disk number AU number
-------------- --------------- ----------- ----------
0 0 3 1155
0 1 0 1124
1 2 0 1125
1 3 2 1131
2 4 2 1132
2 5 0 1126
...
100 200 3 1418
100 201 1 1412
2147483648 0 3 1122
2147483648 1 0 1137
2147483648 2 2 1137
205 rows selected.
由于ASM文件是做了镜像的,我们可以看到每一个虚拟extent有两个物理extent,而且位于不同的磁盘(其实还位于不同的failgroup),但是最有趣的是查询结果的最后三行,虚拟extent的号是2147483648,做了3副本。我们可以通过kfed工具看下这个extent的内容,使用kfed我们首先需要知道ASM磁盘的名称。
通过如下查询获得ASM磁盘的名称:
SQL> select DISK_NUMBER, PATH
from V$ASM_DISK
where GROUP_NUMBER=1;
DISK_NUMBER PATH
----------- ---------------
0 ORCL:ASMDISK1
1 ORCL:ASMDISK2
2 ORCL:ASMDISK3
3 ORCL:ASMDISK4
我们来检查下这些AU中具体存放的内容:
$ kfed read /dev/oracleasm/disks/ASMDISK4 aun=1122 | grep type
kfbh.type: 12 ; 0x002: KFBTYP_INDIRECT
$ kfed read /dev/oracleasm/disks/ASMDISK1 aun=1137 | grep type
kfbh.type: 12 ; 0x002: KFBTYP_INDIRECT
$ kfed read /dev/oracleasm/disks/ASMDISK3 aun=1137 | grep type
kfbh.type: 12 ; 0x002: KFBTYP_INDIRECT
这些额外的AU存放着ASM的元数据,更具体的讲,他们保存了extent map信息,而这些extent map信息不能够存放在ASM的文件目录块中了,因为ASM文件目录块中,只能存放60个extent的条目,一旦超出这个值,那么就要有额外的地方来记录这个信息。由于这属于ASM的元数据,因此被做了3副本(虽然是一个normal冗余的磁盘组),因此每一个大文件都会有这么3个额外的AU,但在一个external冗余的磁盘组中,仅仅只会有这么一个额外的AU,不会被做复制。
Conclusion
ASM空间的占用取决于2个因素:文件的实际大小和磁盘组的冗余度。
在external冗余的磁盘组中,空间的占用:文件实际大小+1个AU(文件头)+1个额外的AU(如果文件大于60个AU)。
在一个normal冗余的磁盘组中,空间的占用:两倍的文件实际大小+2个AU(文件头)+3个额外的AU(如果文件大于60个AU)
在一个high冗余的磁盘组中,空间的占用:三倍的文件实际大小+3个AU(文件头)+3个额外的AU(如果文件大于60个AU)
- 一则数据库无法重启的案例分析(r8笔记第96天)
- 最大公约数和最小公倍数及其应用(Go语言解法)
- JAVA private私有类的 默认构造函数 的生成过程
- 一次数据变更的审核过程(r8笔记第95天)
- JavaScript 学习一
- 与Ajax同样重要的jQuery(2)
- 寻找第K元素的八大算法、源码及拓展
- 索引优先队列-IndexedPrirotyQueue的原理及实现(源码)
- Java 集合系列02之 Collection架构
- 开发者需要掌握的JS事件
- Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
- Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法
- 关于curl网站运维与开发的那些事
- 并查集Union-find及其在最小生成树中的应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- nginx如何限制并发连接请求数?
- RTSP协议视频平台EasyNVR证书配置界面上传文件地址自动填写错误怎么处理?
- 开发RTSP/RTMP/GB28181/海康SDK/EHome视频融合平台EasyCVR,使用vue-cli3项目搭建多页面模式的方法
- 互联网视频直播&点播平台RTMP推流组件EasyRTMP在弱网环境下推流稳定吗?会不会有推流失败的问题?
- 安防融合视频云服务EasyCVR集成海康EHome协议实现设备录像回看返回会话ID为-1是什么情况?
- git .gitignore 忽略规则的匹配语法
- vue 初始化高德地图
- js -- 判断数组是否为空?
- 手机没网了,却还能支付,这是什么原理?
- grub异常
- 34.Python字符串替换方法translate
- 35.Python字符串格式运算符%
- 好一个 Spring Boot 开源在线考试系统!解决了我的燃眉之急
- OC基础--数据类型与表达式
- OC基础--字符串