01 前言
学习任何一门科学,都要从他的背景和宏观体系开始,那么数据库也不例外。
体系结构为什么重要,因为体系结构是对一个系统的框架描述,只有从宏观上掌握它的物理组成、文件组成和各种文件组成,在实际工作遇到疑难问题,都可以归结到体系结构中来解释。
这好比建一栋大楼,你首先应该以图纸的方式把整个大楼的体系架构描述出来。然后一点点的往里面填充东西,今天我们先从Oracle开始了解。
下面我们先以一个图解的方式对oracle体系结构有一个基本了解
示图分三部分组成,左侧用户进程、服务器进程、PGA可以看做成Clinet端,上面的实例(Instance)和下面的数据库(Database)及参数文件(parameter file)、密码文件(password file)和归档日志文件(archived logfiles)组成Oracle Server,所以整个示图可以理解成一个C/S架构。
Oracle Server由两个实体组成:实例(instance)与数据库(database)。这两个实体是独立的,不过连接在一起。在数据库创建过程中,实例首先被创建,然后才创建数据库。在典型的单实例环境中,实例与数据库的关系是一对一的,一个实例连接一个数据库,实例与数据库也可以是多对一的关系,即不同计算机上的多个实例打开共享磁盘系统上的一个公用数据库。这种多对一关系被称为实际应用群集(Real Application Clusters,RAC)RAC极大提高了数据库的性能、容错与可伸缩性(可能耗费更多的存储空间)并且是oracle网格(grid)概念的必备部分。
用户进程(User process): 连接到数据库服务器的进程,用户通过它跟数据库进行交互。但是User process不能直接和数据库进行交互,它必须和服务器的组件Server process进行连接。
服务器进程(Server process): 用来解释由User process传递过来的sql语句,负责commit和rollback,参与IO。启动Server process的时候会分配一块内存区域,叫做PGA(Process Global Area),分为四个部分:堆栈(指向其他PGA内存结构的指针)、session info(保存会话的信息)、cursor info(每个会话游标的信息)、Sort Area(排序区)。PGA区域是私有区域,不能被其他进程所共享。
02 Oracle体系架构
主要有两大部分组成:数据库实例(Instance)和数据库文件(database)
1> 数据库实例
指数据库服务器的内存及相关处理程序,它是Oracle的心脏。数据库实例由内存结构和进程结构组成。
内存结构包含SGA等如下组件:
与Oracle性能关系最大的是SGA(System Global Area,即系统全局区活共享内存区),SGA包含三个部分:
数据缓冲区(Database Buffer Cache),可避免重复读取常用的数据;读数据时,数据在buffer cache,就直接读,如果没有,就找dbf/数据文件。
日志缓冲区(Redo Log Buffer),提升了数据增删改的速度,减少磁盘的读写而加快速度;buffer cache中的数据一旦有修改就会产生该日志,
共享池(Shared Pool),实现代码的共享和重用,使相同的SQL语句不再编译,提升了SQL的执行速度。包含三部分:
库缓存(Library Cache) ,用于存储SQL语句及相关的解析,执行计划,PL/SQL程序块等
共享SQL区 ,存放语法分析结果和执行计划等
私有SQL区 ,存放绑定变量,环境和会话信息等
数据字典缓存(Data Dictionary Cache)
存放数据字典信息,包括表、视图等对象的结构信息,用户以及对象权限信息,按行(row)存储,所以也叫Row Cache结果集(Result Cache) ,缓存查询的结果,可以在服务器端缓存,也可以在客户端缓存
大型池(Large Pool),当有大块内存请求时,可隔离对共享池的性能影响。RMAN备份恢复的时候 ;执行并行查询的时候;执行大量排序操作的时候;共享服务器的时候 都会用到Large Pool。
流池(Streams Pool),用于缓存流进程在数据库间移动/复制数据时使用的队列消息。
JAVA池(Java Pool),是为了减少资源创建、初始化系统开销而采取的一种实现模式,在Java中常见的池一般有连接池,线程池。存储过程可以使用java写。
PGA: 进程/私有全局区
我们在用一张图总结下内存结构
oracle数据库实例的另一部分就是一些后台进程了,他主要包括:
一、用户进程 :当数据库用户或批处理进程连接到Oracle DB时启动
二、数据库进程
1> 服务器进程:可以连接到Oracle实例,在用户建立会话时启动。
2> 后台进程:启动Oracle实例时启动。包含如下,
系统监控进程(SMON),主内,监控实例内部,实例恢复(涉及前滚后滚、锁机制),如整理碎片,清理不使用的临时段。
进程监控(PMON),主外,监控用户连接
在用户进程失败时执行进程恢复
清除数据库缓冲区高速缓存
释放该用户进程使用的资源
监视会话是否发生空闲会话超时
将数据库服务动态注册到监听程序
数据库写进程(DBWR),将buffer cache中的脏数据写入到dbf中,只写不读。
执行时间点:
没有任何可用缓冲区
脏缓冲区过多
三秒超时
遇到检查点
日志写进程(LGWR),log buffer通过LGWR写入到redo log中,写满后会进行切换
LGWR触发条件:
1、用户提交
2、有三分之一的log buffer未被写入磁盘
3、有大于1M的log buffer未被写入磁盘
4、每隔三秒
5、DBWn需要写入的数据的SCN大于LGWR记录的SCN,触发LGWR写入,日志写入优先(Write-Ahead-Log)
检验点进程(CKPT),周期性触发,更新检查点信息,更新到控制文件和每个数据文件头部。
日志归档进程(ARCn),将redo log归档到归档日志
MMON: 自我监视和自我管理支持进程
MMNL:MMON辅助进程
ADDM:自动数据库诊断监视器
MMAN: 自动内存管理
LREG: 监听注册进程
其他进程(Others)
这些后台进程合起来完成数据库管理任务
在访问数据库的时候。服务器后台先启动实例。启动实例前要先分配内存区。然后在启动后台进程。
数据库启动过程中必须启动上面的前五个进程。否则实例无法创建。
同样的,我们用一张图总结下进程结构:
2> 数据库文件,也是我们平常说的Oracle的物理结构
Oracle中主要包括三种文件:
1、数据文件
作用: 用来存储实际数据,数据文件是存储数据的物理概念。
查看:
SQL> col name for a50
SQL> select file#,name,status from v$datafile;
SQL> select * from dba_data_files;
SQL> select * from dba_temp_files;
数据文件的状态
ONLINE: 联机状态
OFFLINE: 脱机状态
OFFLINE DROP: 删除数据文件
每一个ORACLE数据库有一个或多个物理的数据文件(data file)。
一个数据库的数据文件包含全部数据库数据。
逻辑数据库结构(如表、索引)的数据物理地存储在数据库的数据文件中。
2、控制文件
作用:用于记录数据库的物理结构,属于重要角色,没有控制文件,实例立即崩溃,数据库的启动和正常运行都离不开控制文件。
性质: 控制文件是一个二进制文件,不可以通过文本编辑器编辑,该文件由oracle自行维护,oracle建议至少有两份冗余,并且放在不同的磁盘上。
查看:
SQL> show parameters control_files;
SQL> select * from v$controlfile;
默认块大小为16K
每一ORACLE数据库有一个控制文件(control file),它记录数据库的物理结构,包含下列信息类型:
数据库名;
数据库数据文件和日志文件的名字和位置;
数据库建立日期。
为了安全起见,允许控制文件被镜象。
每一次ORACLE数据库的实例启动时,它的控制文件用于标识数据库和日志文件,当着手数据库操作时它们必须被打开。当数据库的物理组成更改时,ORACLE自动更改该数据库的控制文件。数据恢复时,也要使用控制文件。
3、重做日志文件
作用:记录数据文件的每一个变化过程,保证数据库一致性
每一个数据库有两个或多个日志文件(redo log file)的组,每一个日志文件组用于收集数据库日志。日志的主要功能是记录对数据所作的修改,所以对数据库作的全部修改是记录在日志中。在出现故障时,如果不能将修改数据永久地写入数据文件,则可利用日志得到该修改,所以从不会丢失已有操作成果。
日志文件主要是保护数据库以防止故障。为了防止日志文件本身的故障,ORACLE允许镜象日志(mirrored redo log),以致可在不同磁盘上维护两个或多个日志副本。
日志文件中的信息仅在系统故障或介质故障恢复数据库时使用,这些故障阻止将数据库数据写入到数据库的数据文件。然而任何丢失的数据在下一次数据库打开时,ORACLE自动地应用日志文件中的信息来恢复数据库数据文件。
Oralce两种日志文件类型:
联机日志文件
这是Oracle用来循环记录数据库改变的操作系统文件
归档日志文件
这是指为避免联机日志文件重写时丢失重复数据而对联机日志文件所做的备份
Oracle有两种归档日志模式,Oracle数据库可以采用其中任何一种模式:
NOARCHIVELOG
不对日志文件进行归档。这种模式可以大大减少数据库备份的开销,但可能回导致数据的不可恢复
ARCHIVELOG
在这种模式下,当Oracle转向一个新的日志文件时,将以前的日志文件进行归档。为了防止出现历史“缺口”的情况,一个给定的日志文件在它成功归档之前是不能重新使用的。归档的日志文件,加上联机日志文件,为数据库的所有改变提供了完整的历史信息。
在Oracle利用日志文件和归档日志文件来恢复数据库时,内部序列号可以起一个向导的作用。
除了构成Oracle数据库物理结构的三类主要文件外,Oracle数据库还有另外几种重要的文件:
参数文件:记录了Oracle数据库的基本参数信息,主要包括数据库名、控制文件所在路径、进程等。
密码文件:授予用户启动和关闭数据库的实例。主要有二进制数据组成
口令文件:记录超级用户的名字和口令,用来做超级用户的审核。
跟踪文件:ASII码格式的文本文件,记录数据库工作时的一些信息和一些报错内容,用来做trouble shooting。
03 有物理结构,肯定就会有逻辑结构
Oracle的逻辑结构是一种层次结构。主要由:表空间、段、区和数据块等概念组成。逻辑结构是面向用户的,用户使用Oracle开发应用程序使用的就是逻辑结构。数据库存储层次结构及其构成关系,结构对象也从数据块到表空间形成了不同层次的粒度关系。
1.数据块(Data Blocks)
数据块是Oracle最小的存储单位,Oracle数据存放在“块”中。一个块占用一定的磁盘空间。特别注意的是,这里的“块”是Oracle的“数据块”,不是操作系统的“块”。
Oracle每次请求数据的时候,都是以块为单位。也就是说,Oracle每次请求的数据是块的整数倍。如果Oracle请求的数据量不到一块,Oracle也会读取整个块。所以说,“块”是Oracle读写数据的最小单位或者最基本的单位。
块的标准大小由初始化参数DB_BLOCK_SIZE指定。具有标准大小的块称为标准块(Standard Block)。块的大小和标准块的大小不同的块叫非标准块(Nonstandard Block)。
操作系统每次执行I/O的时候,是以操作系统的块为单位;Oracle每次执行I/O的时候,都是以Oracle的块为单位。
Oracle数据块大小一般是操作系统块的整数倍。
数据块的格式(Data Block Format)
块中存放表的数据和索引的数据,无论存放哪种类型的数据,块的格式都是相同的,块由块头(Common and Variable Header),表目录(Table Directory),行目录(Row Directory),空余空间(Free Space)和行数据(Row Data)五部分组成,如下图
块头(Common and Variable Header):存放块的基本信息,如:块的物理地址,块所属的段的类型(是数据段还是索引段)。
表目录(Table Directory):存放表的信息,即:如果一些表的数据被存放在这个块中,那么,这些表的相关信息将被存放在“表目录”中。
行目录(Row Directory):如果块中有行数据存在,则,这些行的信息将被记录在行目录中。这些信息包括行的地址等。
行数据(Row Data):是真正存放表数据和索引数据的地方。这部分空间是已被数据行占用的空间。
空余空间(Free Space):空余空间是一个块中未使用的区域,这片区域用于新行的插入和已经存在的行的更新。
头部信息区(Overhead):我们把块头(Common and Variable Header),表目录(Table Directory),行目录(Row Directory)这三部分合称为头部信息区(Overhead)。头部信息区不存放数据,它存放的整个块的信息。头部信息区的大小是可变的。一般来说,头部信息区的大小介于84字节(bytes)到107字节(bytes)之间。
数据块中自由空间的使用
当往数据库中插入(INSERT)数据的时候,块中的自由空间会减少;当对块中已经存在的行进行修改(UPDATE)的时候(使记录长度增加),块中的自由空间也会减少。
DELETE语句和UPDATE语句会使块中的自由空间增加。当使用DELETE语句删除块中的记录或者使用UPDATE语句把列的值更改成一个更小值的时候,Oracle会释放出一部分自由空间。释放出的自由空间并不一定是连续的。通常情况下,Oracle不会对块中不连续的自由空间进行合并。因为合并数据块中不连续的自由空间会影响数据库的性能。只有当用户进行数据插入(INSERT)或者更新(UPDATE)操作,却找不到连续的自由空间的时候,Oracle才会合并数据块中不连续的自由空间。
2.数据区(Extent)
是一组连续的数据块。当一个表、回滚段或临时段创建或需要附加空间时,系统总是为之分配一个新的数据区。一个数据区不能跨越多个文件,因为它包含连续的数据块。使用区的目的是用来保存特定数据类型的数据,也是表中数据增长的基本单位。在Oracle数据库中,分配空间就是以数据区为单位的。一个Oracle对象包含至少一个数据区。设置一个表或索引的存储参数包含设置它的数据区大小。
3.段(Segment)
是由多个数据区构成的,它是为特定的数据库对象(如表段、索引段、回滚段、临时段)分配的一系列数据区。段内包含的数据区可以不连续,并且可以跨越多个文件。使用段的目的是用来保存特定对象。
一个Oracle数据库有4种类型的段:
数据段:数据段也称为表段,它包含数据并且与表和簇相关。当创建一个表时,系统自动创建一个以该表的名字命名的数据段。
索引段:包含了用于提高系统性能的索引。一旦建立索引,系统自动创建一个以该索引的名字命名的索引段。
回滚段:包含了回滚信息,并在数据库恢复期间使用,以便为数据库提供读入一致性和回滚未提交的事务,即用来回滚事务的数据空间。当一个事务开始处理时,系统为之分配回滚段,回滚段可以动态创建和撤销。系统有个默认的回滚段,其管理方式既可以是自动的,也可以是手工的。
临时段:它是Oracle在运行过程中自行创建的段。当一个SQL语句需要临时工作区时,由Oracle建立临时段。一旦语句执行完毕,临时段的区间便退回给系统。
4.表空间(tablespace)
是数据库的逻辑划分。任何数据库对象在存储时都必须存储在某个表空间中。表空间对应于若干个磁盘文件,即表空间是由一个或多个磁盘文件构成的。表空间相当于操作系统中的文件夹,也是数据库逻辑结构与物理文件之间的一个映射。每个数据库至少有一个表空间(system tablespace),表空间的大小等于所有从属于它的数据文件大小的总和。
(1)系统表空间(system tablespace)
是每个Oracle数据库都必须具备的。其功能是在系统表空间中存放诸如表空间名称、表空间所含数据文件等数据库管理所需的信息。系统表空间的名称是不可更改的。系统表空间必须在任何时候都可以用,也是数据库运行的必要条件。因此,系统表空间是不能脱机的。
系统表空间包括数据字典、存储过程、触发器和系统回滚段。为避免系统表空间产生存储碎片以及争用系统资源的问题,应创建一个独立的表空间用来单独存储用户数据。
(2)SYSAUX表空间
是随着数据库的创建而创建的,它充当SYSTEM的辅助表空间,主要存储除数据字典以外的其他对象。SYSAUX也是许多Oracle 数据库的默认表空间,它减少了由数据库和DBA管理的表空间数量,降低了SYSTEM表空间的负荷。
(3)临时表空间
相对于其他表空间而言,临时表空间(temp tablespace)主要用于存储Oracle数据库运行期间所产生的临时数据。数据库可以建立多个临时表空间。当数据库关闭后,临时表空间中所有数据将全部被清除。除临时表空间外,其他表空间都属于永久性表空间。
(4)撤销表空间
用于保存Oracle数据库撤销信息,即保存用户回滚段的表空间称之为回滚表空间(或简称为RBS撤销表空间(undo tablespace))。在Oracle8i中是rollback tablespace,从Oracle9i开始改为undo tablespace。在Oracle 10g中初始创建的只有6个表空间sysaux、system、temp、undotbs1、example和users。其中temp是临时表空间,undotbs1是undo撤销表空间。
(5)USERS表空间
用户表空间,用于存放永久性用户对象的数据和私有信息。每个数据块都应该有一个用户表空间,以便在创建用户是将其分配给用户。
堆字不容易,关注点赞,手有余香~