百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

Oracle逻辑体系实验(oracle逻辑结构组件从大到小)

sinye56 2024-09-19 02:26 3 浏览 0 评论



逻辑体系

体系物理结构:数据文件、参数文件、控制文件、日志文件、归档文件


数据文件是存放数据之处,也是数据库存在的根本!

逻辑结构:表空间(tablespace)、段(segment)、区(extent)、块(block)。


数据库(database)由若干表空间组成,表空间由若干段组成,段由若干区组成,区又是由Oracle的最小单元块组成的。

表空间又包含系统表空间、回滚段表空间、临时表空间、用户表空间。除了用户表空间外,其他三种表空间有各自特定的用途,不可随意更改和破坏,尤其是系统表空间更是需要被小心谨慎地保护。

一系列连续的block组成了extent,一个或多个extent组成了segment,一个或多个segment组成了tablespace,而一个或多个tablespace组成了database(一个database要想存在,至少需要有SYSTEM及undo表空间)。

DML语句更新表,实质是更新Oracle磁盘的数据库文件(datafile),只是会有一个从Data Buffer中先更新再刷到磁盘的过程(直接路径方式除外)

表是就从数据文件里直观抽象出来的逻辑结构。

表和段直接对应的。表并不是只对应一个段,如表中包含LOB类型的列,则LOB至少会有两个段,数据段和索引段,如表有分区,则每个分区又都独立成段


t段、t2段、t3段都属于tbs_test表空间,tbs_test表空间是由t段、t2段、t3段等组成的。

段是由区组成的,而区又是由一系列数据块组成的,数据插入某个区 extent1的第1个数据块中,很快就插满了,然后插入第2个同属于该extent1区的连续数据块,接下来第2个块又插满了,插第3个块……当准备插第11个数据块时,这个区满了。接下来只好插入另外一个区extent2,直至插完extent3、extent4后,插入结束。而这些extent1、extent2、extent3、extent4组成了t段,也就是张三的t表。

Oracle的这个区的设计是为了避免过度扩展,因为块的尺寸太小了,如果以块为单位进行扩展,就不会导致频繁申请。

block是Oracle中的最小逻辑数据单位,但是所有数据在文件系统层面最小物理存储单位是字节,操作系统中也有一个类似Oracle的块容量的参数(blocksize),但是Oracle总是访问整个Oracle block,而不是按照操作系统的blocksize来访问的。一般情况下大多数操作系统的块容量为512字节或其整数倍,而数据块一般被默认设置为8KB,除此之外也有系统将其设置为2KB、4KB、16KB、32KB、64KB等其他大小。但是数据库的block一般要设置为操作系统块容量的整数倍,这样可以减少IO操作,数据库是运行在操作系统上的,而写入的数据文件也是操作系统中的文件,因此真正操作的单位应该是操作系统块的大小。

假如IO的大小设置为512字节(0.5KB),本来如果数据库的block设置为1KB正好是其两倍,但是设置为0.8KB,这时由于操作系统的单个块大小为0.5KB,需要两个操作系统块才可容纳下,于是就动用了两个操作系统块去容纳,相当于占用了1KB大小的空间,浪费了0.2KB。

Oracle的数据块并不是简单地往里插数据,插满了装不下了就插入另一个数据块这么简单,而是额外提供了一定的管理功能。

数据库的组成分为数据块头(包括标准内容和可变内容)(common and variable header)、表目录区(table directory)、行目录区(row directory)、可用空间区(free space)、行数据区(row data)这5个部分。

把数据块分成了5个部分。

1.数据块头(header)中包含了此数据块的概要信息,例如块地址(blockaddress)及此数据块所属的段的类型(比如到底是表还是索引)。

2.表目录区:只要有一行数据插入到数据块中,那该行数据所在的表的信息将被存储在这个区域。

3.行目录区中存放插入的行的地址。

4.可用空间区就是块中的空余空间。这个空余的多少由Oracle的PCTFREE参数设置,如果是10,表示该块将会空余10%左右的空间。此外,如果是表或者索引块,该区域还会存储事务条目,大致有23字节左右的开销。


5.行数据区存储的是具体的行的信息或者索引的信息,这部分占用了数据块绝大部分的空间。

数据块头、表目录区、行目录区被统称为管理开销(overhead),其中有些开销的容量是固定的,而有些开销的总容量是可变的。数据块中固定及可变管理开销的容量平均在84字节到107字节之间。

把一些连续的数据块组合在一起,就形成了区。Oracle中这个被称为区的数据库逻辑存储分配单位就是这么形成的。

区是Oracle数据库分配空间的最小单位,请注意分配这两个字。

当某用户创建一张表T时,实质就是建了一个数据段segment T。在Oracle数据库中,只要segment创建成功,数据库就一定为其分配了包含若干数据块的初始数据扩展(initial extent),即便此时表中还没有数据,但是这些初始数据扩展中的数据块已经为即将插入的数据做好准备了。接下来向T表(也就是segment T)中插入数据,很快初始数据扩展中的数据块就都装满了,而且又有新数据插入需要空间,此时 Oracle 会自动为这个段分配一个新增数据扩展(incremental extent),这个新增数据扩展是一个段中已有数据扩展之后分配的后续数据扩展,容量大于或等于之前的数据扩展。可以调整数据库的区的大小。



每个段的定义中都包含了数据扩展的存储参数(storage parameter)。存储参数适用于各种类型的段。这个参数控制着Oracle如何为段分配可用空间。

例如,用户可以在CREATE TABLE语句中使用STORAGE子句设定存储参数,决定创建表时为其数据段分配多少初始空间,或限定一个表最多可以包含多少数据扩展。如果用户没有为表设定存储参数,那么表在创建时使用所在表空间(tablespace)的默认存储参数。

在一个本地管理的表空间中(注,还有一种数据字典管理的表空间,是一种要被淘汰的技术),其中所分配的数据扩展的容量既可以是用户设定的固定值,也可以是由系统自动决定的可变值。

取决于用户创建tablespace时用 UNIFORM 指令(固定大小)还是AUTOALLOCATE指令(由系统管理)。“对于固定容量(UNIFORM)的数据扩展,用户可以为数据扩展设定容量(比如100MB、1GB等随你设定)或使用默认大小(1 MB)。用户必须确保每个数据扩展的容量至少能包含5个数据块。

本地管理(locally managed)的临时表空间(temporary tablespace)在分配数据扩展时只能使用此种方式。



由系统管理(AUTOALLOCATE)的数据扩展,就无从插手干预了,Oracle或许一个区申请20MB,下一个区忽然申请100MB,Oracle在运行过程中自行决定新增数据扩展的最佳容量,无从得知规律。不过还是有一个下限的,即区的扩展过程中其最小容量不能低于64KB,假如数据块容量大于或等于16 KB,这个下限将从64KB转变为1 MB。

表空间的分类

区是由一系列块组成的、段是由一系列区组成的,一系列段组成表空间!

系统表空间、临时表空间、回滚表空间、数据表空间

实验

以下试验是通过观察数据库数据字典以及show parameter 参数的方式来实现的。

试验顺序是这样的:先建表空间(数据表空间、临时表空间和回滚段表空间),然后建指定用户,该用户登录后,在指定的表空间建表和建索引。

实验 逻辑结构之block

说明数据库的块大小是8KB,这是Oracle的最小逻辑单位。



实验 逻辑结构之tablespace

建各类表空间的方法




实验 逻辑结构之user

要指定用户的默认表空间是某指定表空间,那么必须先建立该表空间



实验 逻辑结构之extent

Oracle的最小逻辑单位是块,而最小的扩展单位是区extent,这两个‘最小’请务必牢记。



实验——逻辑结构之segment




块的大小与调整

Oracle默认的数据块大小就是8KB,是在创建数据库时决定的,所以如果想改变块的大小,就必须在建库时指定。

在Oracle 9i以后的版本中,Oracle支持用户在新建用户表空间时指定块的大小,这意味着数据库有多个表空间,它们各自的块大小有可能各不相同。

切记只是新建自己的用户表空间,不可能更改原有的已经建好的表空间,更不可能更改或调整系统表空间


可以设置2KB、4KB、8KB、16KB、32KB的块大小,当把db_16k_ cache_size设置为100MB时,意味着SGA中的Data Buffer数据缓存区中将会有100MB的大小让内存块可以以16KB大小进行访问,同时也意味着16KB大小的设置从此生效了。

设置一个表空间,让其 block_size 尺寸为16KB,首先需要将db_16k_cache_size取值设置为非空


创建表空间,切记加上blocksize 16K



PCTFREE参数与调整

块有一个FREE空间,是由PCTFREE参数决定的

数据库中某表T 有900行记录,如果一个块最多可以装10行记录,最终需要90个块将T表记录装满。如果PCTFREE为10,表示会预留10%的空间,那就是每个块都只能装9行数据,最终需要100个块才可以把T表记录装满。

这时做一个全表扫描的查询,查询T 表的所有记录,如果PCTFREE 设置为10,我们将会遍历100个数据块,如果PCTFREE为0,我们将遍历90个数据块。

如果PCTFREE设置为0,块将装下更多行的记录,需要的块的数量就少了,但是只有在只读数据库或者只有插入删除很少更新的数据库环境中,才适合将PCTFREE设置为0,当有插入的时候可以直接把数据插入到预留的空间中。

过度扩展与性能

区是 Oracle 数据库扩展的最小单位,而且大小是可以设置的。

根据这两点我如果某个表(或者说某段)中的记录增长得特别快,就可以考虑把这个区的大小设置得大一点,比如将initial extent和incremental extent都设置得比较大,这样申请扩展的次数就会减少,性能可以提高——没啥意义,提升性能不大,区申请性能消耗并不大,当然如果特别频繁那另外一说。

建两个表空间,一个是 TBS_LJB_A,一个是TBS_LJB_B:


分别在两个表空间上创建t_a和t_b表


由于是插入1000万条记录,TBS_LJB_A表空间的1MB大小很快就不够装了,不断自动扩大空间是可以预计的动作。而TBS_LJB_B表空间大小是固定的2GB,足够容纳插入的1000万条记录。


一个是2分13秒,一个是21秒,t_a段扩展了1919次,而t_b段才扩展了86次,这就是速度差好几倍的原因。

真正的原因其实是表空间在申请扩大空间时花费了大量时间


TBS_LJB_C表空间本身就够装下插入1000万行记录后的T表,表空间不需要扩展,速度也还不错,22秒即可完成,与前面的21秒差别不大。

对 Oracle 来说,表空间扩大是要格式化操作系统文件成为 Oracle可以识别的数据库,这当然需要很大的开销了。如果空间已经足够大,其中的段申请扩展,那都是可以识别的格式,无须格式化动作,开销就不是太大了。

在创建表空间时,需要预先规划好表空间的大小,如果段的扩展导致表空间不够而需要表空间去扩大,那开销是很大的,但是如果预先分配过多,也是一种浪费,需要我们根据实际应用去平衡。

PCTFREE与性能

可以根据数据库对表更新的频繁程度对表的PCTFREE做设置,免得产生行迁移,影响性能

用户HR是Oracle建库时自带的一个供大家参考的测试用户


将几个字段扩大


在几个从20字节扩大为2000字节的字段中填满数据,这必然会导致产生大量的行迁移:



对这个表进行一个普通的查询,会发现仅107行的记录居然产生了356个逻辑读。

其中select * from EMPLOYEES WHEREEMPLOYEE_ID=100;被反复执多次,取最终递归调用和物理读都为0时的结果比较公正:


下面我们用EMPLOYEES新建一个EMPLOYEES_BK表,这等于消除了行迁移,发现逻辑读减少了许多,从31缩减为20(其中select * from EMPLOYEES_BK;也是执行过2次以上的结果,保证公正)


原先填充20字节的长度被更新为2000字节的长度,好比小不点忽然变成超级大胖子,行迁移是必然的,而且是大批量的。这里才100多条记录的小表,逻辑读居然就差别如此之大!

消除行迁移的一个简单方法,就是数据重建,这个EMPLOYEES_BK表就没有行迁移现象,所以逻辑读少多了!

这里是默认取值,EMPLOYEES 表的 PCTFREE 默认为10,查询数据库:



这个参数到底该设置为多大,是需要深入了解和测试的,这并不简单。实际工作中也有不少调整这个参数优化数据库系统的案例,并取得了不错的效果!

行迁移与优化


通过这个方法,可以了解到哪些数据库表中存在行迁移严重的情况,对它们做适当的改进,比如重建新表消除行迁移,然后再对 PCTFREE 做适当的调整,等等。

对当前用户的所有表做分析:



块的大小与应用

块是Oracle最小的单位。如果Oracle是单块读,则一次读取一个块,就是一个IO。

如果是一次读取多个块,那还是算一个IO,称之为多块读。

如果块越大,装的行记录越多,那么所需要的块就越少,换句话说,读取记录产生的IO就越少,因此块设置可以理解为越大越好。

对于数据仓库 OLAP 的数据库应用,一般倾向于将块设置得尽量大,而对于OLTP应用,块不要设置得太大。OLAP和OLTP的差别在于,前者一般查询返回大量的数据,而后者查询返回极少量数据。前者一般用户不多,并发不大,后者一般用户很多,并发很大。因此OLAP应用用得最多的查询方式应该是全表扫描,而OLTP应用用得最多的查询方式应该是索引读。


在这两个表空间中分别构造两张记录达到300多万的大表,并建索引。在块为16KB的TBS_LJB_16K表空间完成t_16k这个表的准备工作:



在块大小为8KB的TBS_LJB表空间中构造环境,完成大表t_8k的准备工作



观察select count(*)from t_16k;的性能


观察select count(*)from t_8k;的性能


块大小为16KB的TBS_LJB_16K表空间中的查询需要1分20秒,而块大小为8KB的表空间中的查询需要2分9秒。逻辑读差别也很大,在类似OLAP系统的环境下,块大小设置得越大性能越会有提升。但是在索引读的环境下,就没有什么性能优势了。

在块大小为8KB的环境下,执行select * from t_8k where object_id=29;:


在块大小为16KB的环境下,执行select * from t_16k where object_id=29;


在索引读返回少量记录这样的OLTP主打环境下,块的大小对性能影响不大。如果块太大,容易导致大量并发查询及更新操作都指向同一个数据块,从而产生热点块竞争。

相关推荐

Linux在线安装JDK1.8

首先在服务器pingwww.baidu.com查看是否可以连网然后就可以在线下载一、下载安装JDK1.81、在下载安装的同时做好一些准备工作...

Linux安装JDK,超详细

1、了解RPMRPM是Red-HatPackageManager(RPM软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux...

Linux安装jdk1.8(超级详细)

前言最近刚购买了一台阿里云的服务器准备要搭建一个网站,正好将网站的一个完整搭建过程分享给大家!#一、下载jdk1.8首先我们需要去下载linux版本的jdk1.8安装包,我们有两种方式去下载安装...

Linux系统安装JDK教程

下载jdk-8u151-linux-x64.tar.gz下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.ht...

干货|JDK下载安装与环境变量配置图文教程「超详细」

1.JDK介绍1.1什么是JDK?SUN公司提供了一套Java开发环境,简称JDK(JavaDevelopmentKit),它是整个Java的核心,其中包括Java编译器、Java运行工具、Jav...

Linux下安装jdk1.8

一、安装环境操作系统:CentOSLinuxrelease7.6.1810(Core)JDK版本:1.8二、安装步骤1.下载安装包...

Linux上安装JDK

以CentOS为例。检查是否已安装过jdk。yumlist--installed|grepjdk或者...

Linux系统的一些常用目录以及介绍

根目录(/):“/”目录也称为根目录,位于Linux文件系统目录结构的顶层。在很多系统中,“/”目录是系统中的唯一分区。如果还有其他分区,必须挂载到“/”目录下某个位置。整个目录结构呈树形结构,因此也...

Linux系统目录结构

一、系统目录结构几乎所有的计算机操作系统都是使用目录结构组织文件。具体来说就是在一个目录中存放子目录和文件,而在子目录中又会进一步存放子目录和文件,以此类推形成一个树状的文件结构,由于其结构很像一棵树...

Linux文件查找

在Linux下通常find不很常用的,因为速度慢(find是直接查找硬盘),通常我们都是先使用whereis或者是locate来检查,如果真的找不到了,才以find来搜寻。为什么...

嵌入式linux基本操作之查找文件

对于很多初学者来说都习惯用windows操作系统,对于这个系统来说查找一个文件简直不在话下。而学习嵌入式开发行业之后,发现所用到的是嵌入式Linux操作系统,本想着跟windows类似,结果在操作的时...

linux系统查看软件安装目录的方法

linux系统下怎么查看软件安装的目录?方法1:whereis软件名以查询nginx为例子...

Linux下如何对目录中的文件进行统计

统计目录中的文件数量...

Linux常见文件目录管理命令

touch用于创建空白文件touch文件名称mkdir用于创建空白目录还可以通过参数-p创建递归的目录...

Linux常用查找文件方法总结

一、前言Linux系统提供了多种查找文件的命令,而且每种查找命令都具有其独特的优势,下面详细总结一下常用的几个Linux查找命令。二、which命令查找类型:二进制文件;...

取消回复欢迎 发表评论: