以前对数据库的了解大多数是集中在 mysql,最近工作里面一直使用的是 Oracle ,虽然说在互联网行业 mysql 大行其道,但是一些传统行业或者是金融领域还是更加倾向于使用 oracle,sqlserver 这种大型数据库。为此还是有必要深入了解以下 oracle 的一些内部机制的。
有过 oracle 使用经验的人都知道表空间(tablespace)的概念,表空间其实是一个逻辑概念,它并不实际存在。而与之关系密切的是数据文件(datafile),数据文件是实际存在的,并且和表空间是多对 1 的关系。其实只知道这些是远远不够的,前段时间遇到一个数据文件超过 32G 导致的业务问题,才突然醒悟骚年静下心好好学习学习 oracle 底层的一些概念才是解决问题的王道。首先我们从整体来上了解一下 oracle 的逻辑体系结构。在这里附上一张百度到的图片。
图片中展示的 oracle 的最大的逻辑结构为数据库,其实这里最大的体系结构应该是实例(instance),并且实例和数据库是一对一的关系,这样的话我们可以将上图看作是 oracle 体系结构中的一个可分割的最大单元。 可以看出数据库可划分的最大单元为表空间,而表空间又由段(segment)组成,段由 extent 构成,如果再往下分的话是 block,oracle 中 block 的概念不同于操作系统中块文件的概念,这个我们后面章节解释。下面我们对上述的一些概念进行一下阐述:
表空间:表空间是 oracle 抽象出来的最大的逻辑单元,用于存储数据库对象。和表空间相关的概念为数据文件,可以通过 dba_data_files 来查看表空间和数据文件的关系。
表空间分类:
段: 段是指占用数据文件空间的通称,或数据库对象使用的空间的集合;段可以有表段、索引段、回滚段、临时段和高速缓存段等。说到这里有必要提一下表段,因为标段中如果表作为一个分区表,那么表的一个分区占用一个段。
段分类: 由于 oracle 中段比较多,这里我们只是简单的说一些比较常见的段。
区:区是 oracle 中由块组成的逻辑单元,在 10G 中只要创建了表的时候就会分配区,而在 11G 及其之后是当插入数据的时候才会分配区。区的分配则是动态的,当表的容量超过当前区所能承载的范围时就会自动添加新的区。这个内容可以通过 dba_extents 表查看。
块: oracle 的块是建立在数据库块的基础之上的,通常 oracle 的块可以是 2,4,8,16,32K,是系统块的整数倍,并且定义之后不能被修改。在这里引入一个前段时间遇到的问题: oracle 数据文件超过 32G 导致业务失败的问题。这是因为测试环境上面使用的是 smallfile tablespace 模式,所以需要满足以下制约:
由于 Oracle 的 Rowid 中使用 22 位来代表 Block 号,这 22 位最多只能代表 2^22-1(4194303) 个数据块,而在我们一般情况下使用的数据块大小为 8k,所以数据文件的理论大小最大为: 31.9999924G,并且在数据文件超过 32G 的情况下,唯一能做的就是添加一个 datafile。
来源: http://www.linuxidc.com/Linux/2017-12/149632.htm