下面是我整理(抄袭)的一些oracle数据库相关概念对象的理解,如有疏漏,欢迎指正。至于整理这篇文章的目的:主要是网上的内容太散了,这样整理一遍可以加深理解,也便于后续查阅。就我的理解:下述内容应该可对10g,11g,12c都适用。更新的版本没用过。
oracle database是一款关系型数据库管理系统,很多时候,我们会把那个承载我们核心数据的系统笼统地成为数据库服务器,但从严格意义上来讲oracle database是由两个部分组成:
其中:
数据库指的是用户存储数据的一些物理文件,数据库 = 物理结构+逻辑结构
实例是数据库启动时初始化的一组进程和内存结构,实例 = 后台进程 + 内存
正因为如此我们一般才会说关闭和启动实例,加载和卸载数据库,就是这个道理。从实例和数据库的概念上来看,我们能知道,实例是暂时的,它不过是一组逻辑划分的内存结构和进程结构,它会随着数据库的关闭而消失,而数据库它其实就是一堆物理文件,它是永久存在的(除非磁盘损坏)。数据库和实例通常是一对一的,这种结构我们称为单实例体系结构;当然还有一些复杂的分布式的结构,一个数据库可以对多个实例,像oracle的rac(请自行google或者baidu),即集群模式。
下图是对一个oracle数据库服务,更具体的结构展示:
当在计算机服务器上启动oracle数据库后,称服务器上启动了一个oracle实例(instance)。oracle 实例(instance)是存取和控制数据库的软件机制,它包含系统全局区(sga)和oracle进程两部分。sga是系统为实例分配的一组共享内存缓冲区,用于存放数据库实例和控制信息,以实现对数据库中数据的治理和操作。 进程是操作系统中一个极为重要的概念。一个进程执行一组操作,完成一个特定的任务。对oracle数据库治理系统来说,进程由用户进程、服务器进程和后台进程所组成。 当用户运行一个应用程序时,系统就为它建立一个用户进程。服务器进程处理与之相连的用户进程的请求,它与用户进程相通讯,为相连的用户进程的oracle请求服务。 为了提高系统性能,更好地实现多用户功能,oracle还在系统后台启动一些后台进程,用于数据库数据操作。 下面具体说明oracle数据库的相关概念
一、oracle数据库实例 这一部分主要参考(抄袭): https://blog.csdn.net/ochangwen/article/details/51171992
1、 用户与oracle数据库的交互流程 下面这张图,描述了单实例体系结构大致的交互流程 (1)用户和用户进程交互 用户进程可以是一般的客户端软件,像oracle的sqlplus,sql developer,或者是一些驱动程序等,都属于用户进程。 (2)用户进程和服务器进程交互 服务器进程有时会称为前台进程,当然是相对于后台进程(后面会提到的数据库写入器,日志写入器等)来说的,服务器进程的主要作用就是处理连接到当前实例的用户进程的请求,对客户端发来的sql进行执行并返回执行结果。在专有服务器结构中,用户进程和服务器进程是一对一的,也就是说,当监听程序监听到客户端来了一个请求,会为其分配一个对应的服务器进程。还有一种结构为共享服务器,这种结构就不是一个用户进程对应一个服务器进程了,会通过调度程序进行协调处理,关于共享服务器连接,本文在此就不叙述了。 (3)服务器进程和实例进程交互 (4)实例和数据库进程交互 上面描述了一些我们在进行数据库连接操作的时候,大致的交互流程是什么样的。下面,我们就来看看oracle 的实例内存结构
2.实例内存结构 (由于数据库写入器和日志写入器和内存结构非常相关,而且非常重要,所以内存结构和这两个进程结构会相互配合地进行描述) oracle实例内存结构由两部分组成:sga(系统全局区)和pga(用户全局区),sga是一块共享的内存区域,也是最大的一块内存区域,它包含该实例的数据和控制信息。sga在实例启动时被自动分配,当实例关闭时被收回。数据库的所有数据操作都要通过sga来进行;pga则是用户会话专有的内存区域,每个会话在服务器端都有一块专有的内存区域就是pga。本文主要对sga进行分析描述。sga组成如下: (1)数据库缓冲区缓存&数据库写入器 缓冲区缓存(buffer cache)是oracle用来执行sql 的工作区域,在更新数据时,用户会话不会直接去更新磁盘上的数据,想想,如果允许这么做,那么频繁的磁盘io对于系统性能的影响是毁灭性的。所以,
实际的处理流程是这样的:
对于一条简单的查询语句——select ename,salary from emp where name=’不二’;,当用户提交了该条sql语句,该条sql语句会由对应的用户进程(比如我们常用的sql developer)发送给服务器,监听程序监听到该条请求,oracle会为其建立一个对应的服务器进程,然后服务器进程会先扫描缓冲区中有没有包含关键行(”不二”)的数据块,如果有,这就算一次缓存命中了,然后相关行会传输到pga进行进一步处理,最终经过格式化后展示给用户;如果没有命中,那么服务器进程会首先将对应行复制到缓冲区内,然后再返回给客户端。
dml(insert,update,delete)操作同理,加入用户发送一条update语句,服务进程依然先去扫描缓冲区,如果缓存命中,则直接更新,数据变脏;如果没有命中,由服务器进程将对应数据块先从磁盘上复制到缓冲区内,再进行更新操作。 1)脏缓冲区 如果缓冲区存储的块和磁盘上的块不一致,该缓冲区就叫做“脏缓冲区”,脏缓冲区最终会由数据库写入器(dbwn)写入到磁盘中去。 2)数据库写入器(dbwn) 数据库写入器是oracle的一个后台进程,所谓后台进程是相对于前台进程(服务器进程)来讲的。dbwn的”n”意味着一个实例是可以有多个数据库写入器的。 作用:简而言之,dbwn的作用就是将变脏了的缓冲区从数据库缓冲区缓存中写入到磁盘中的数据文件中去。 数据库缓冲区缓存这块内存区域和数据库写入器这块是比较重要的概念,别的数据库产品像mysql也都有对应的实现,只不过叫法不一样罢了。了解这块的时候,要时刻意识到
会话是不会直接更新磁盘数据的,会话的更新,插入,删除包括查询等都是先作用到缓冲区上,随后,dbwn会将其中的脏缓冲区转储到磁盘上去。 3)dbwn执行写入的触发条件:
dbwn是个比较懒的进程,它会尽可能少的进行写入,在以下四种情况它会执行写入: a.一个服务进程在设定的时间内没有找到空闲块(没有任何可用缓冲区,不得不写啊) b.脏缓冲区过多 c.3秒超时(每3秒自动唤醒一次) d.遇到检查点,即checkpoint(检查点),检查点是个oracle事件,遇到检查点,dbwn会执行写入。比如实例有序关闭的时候会有检查点,dbwn会将所有脏缓冲区写入到磁盘上去的,这很容易理解,要保持数据文件的一致性。 4)注意: 从上述dbwn的几个写入时机,我们能意识到,dbwn的写入不是直接依赖于会话的更新操作的。不是一有脏缓冲区,它就执行写入。而且,
dbwn执行写入跟commit操作也没有任何关系,不要以为commit操作的影响结果会实时流入到磁盘中去。 dbwn采用极懒算法进行写入,原因我们应该要清楚:频繁的磁盘io对系统的压力很大,如果dbwn很积极地去写入磁盘,那对系统性能的影响就太大了,换个角度想,如果dbwn很勤快的写磁盘,那么数据库缓冲区存在的意义也就不大了。 当然,讲到这儿,我们可能会意识到一个问题,dbwn如此懒地进行数据转储,如果在某一时刻,数据库缓冲区缓存内存在着大量的脏缓冲区(生产环境中,这是常态),也就是有大量的未commit和已commit的数据还在内存中,没有持久化到磁盘中,然后突然系统断电了,这种情况下,数据是不是就丢掉了?数据当然不会丢失,这就引出了重做日志(redo log)的概念,接下来,我们就来谈谈对应重做日志的内存结构和后台进程。 (2) 日志缓冲区&日志写入器 当我们执行一些dml操作(insert,update,delete),数据块发生改变了,产生的变更向量则会写入到重做日志文件中去。有了这些记录,当系统由于断电等因素突然宕掉,数据库缓冲区缓存内的大量脏数据还没来得及写入到数据文件中去,在重新启动的时候,会有一个实例恢复的过程,在此过程中就应用了重做日志记录来使数据保持一致;或者数据库遭遇了物理损坏,比如磁盘损坏了,此时可以通过oracle的备份恢复工具(如rman)进行数据恢复,原理就是:提取备份集–>应用重做日志文件中的变更记录。 1)日志缓冲区(log buffer) 日志缓冲区是一块比较小的内存区域,它是用来短期存储,即将写入到磁盘的重做日志文件中的变更向量。 日志缓冲区存在的意义依然是为了减少磁盘io,减少用户的等待时间,试想下,如果每一次用户dml操作都要进行等待重做记录被写入到磁盘中去,体验会有多差劲。 2)日志写入器(lgwr) 作用:日志写入器(lgwr)就是把日志缓冲区(log buffer)内的内容写入到联机的磁盘的重做日志文件中去,释放log用户buffer空间。相比数据库写入器(dbwn),日志写入器就勤快多了。 3)lgwr执行写入的触发条件: a.commit时写入 前面提过,dbwn的写入和commit没有任何关系,如果commit时数据库没有任何记录,那数据就真的丢失了,oracle 的重做日志就是为了保证数据安全而存在的,用户commit时(在oracle中称为快速提交机制(fast commit):把redo log buffer中的记录写入日志文件,写入一条提交的记录),会话会先挂起,等待lgwr将这些记录写入到磁盘上的重做日志文件中,才会通知用户提交完成。所以,
lgwr在commit时执行写入,是为了确保事务永不丢失。 b.3秒超时(每3秒自动唤醒一次) c.日志缓冲区的占用率达到1/3,或日志数量超过1m。 d.dbwr进程触发:dbwn将脏缓冲区写入磁盘前,先检测他的相关redo记录是否写入联机日志文件,如果没有就通知lgwr进程。在oracle中称为提前写机制(write ahead):redo记录先于数据记录被写入磁盘。这个写入是为了数据回滚考虑的。dbwn完全可能写入还没提交的事务(参照上面提到的写入时机),那如何保证事务回滚呢?(注:dbwr全称是database writer process,属于oracle后台进程的一种,有的地方也叫dbwn,我想这里是出于dbwr进程个数的原因,dbwr进程在一个oracle server中可以最多有20个。本文聚合了很多篇文章,如果遇到dbwr和dbwn,请做同一名词处理) 首先要知道,dbwn除了写入实际的数据,还会写入撤销数据(可以参考:oracle闪回技术)简单说,事务回滚需要撤销数据,在写入撤销数据前,会先写入针对撤销数据的日志记录(有点绕),
若用户要进行事务回滚,就可以应用这些日志记录来构造撤销数据,然后进行回滚。
我们对这两块最重要的内存区域和对应的后台进程做个总结:
数据库缓冲区缓存和日志缓冲区都是为了提高性能,避免频繁io而存在的。日志缓冲区相比数据库缓冲区缓存要小的多,并且不能进行自动管理,对于日志缓冲区的修改需要重启实例,数据库缓冲区缓存可进行自动管理。作用在数据库缓冲区缓存上的dbwn进程,为了避免频繁的磁盘io导致系统性能下降,会尽可能少地执行写入,且dbwn的写入和commit操作没有任何关系;
而作用在日志缓冲区上的lgwr进程,则会非常积极地进行写入,一般情况下,它几乎是实时地将重做日志记录转储到磁盘中去。lgwr是oracle体系结构中最大的瓶颈之一。dml的速度不可能超过lgwr将变更向量写入磁盘的速度。 (3)共享池 共享池包含共享sql区和数据字典存储区。共享sql区包含执行特定的sql语句所用的信息。数据字典区用于存放数据字典,它为所有用户进程所共享。 它是最复杂的sga结构,它有许多子结构,我们来看看常见的几个共享池组件: 1)库缓存:库缓存这块内存区域会按已分析的格式缓存最近执行的代码,这样,同样的sql代码多次执行的时候,就不用重复地去进行代码分析,可以很大程度上提高系统性能。 2)数据字典缓存:存储oracle中的对象定义(表,视图,同义词,索引等数据库对象),这样在分析sql代码的时候,就不用频繁去磁盘上读取数据字典中的数据了 3)pl/sql区:缓存存储过程、函数、触发器等数据库对象,这些对象都存储在数据字典中,通过将其缓存到内存中,可以在重复调用的时候提高性能。 (4)大池 大池是个可选的内存区域,前面我们提到专有服务器连接和共享服务器连接,如果数据库采用了共享服务器连接模式,则要使用到大池;rman(oracle的高级备份恢复工具)备份数据也需要大池。 (5) java池 oracle 的很多选项使用java写的,java池用作实例化java对象所需的堆空间 (6)流池 从重做日志中提取变更记录的进程和应用变更记录的进程会用到流池(如实例不正常关闭,譬如断电导致实例关闭,在重启时,oracle会自动执行实例恢复过程,在此过程需要提取重做日志记录和应用重做日志两个动作) 以上列举了oracle常见的内存结构,要注意的是,上面列举的内存区域,除了日志缓冲区是固定的,不能动态调整也不能进行自动管理外,其他内存区域都可以进行动态调整,也可以进行自动管理。
3.实例进程结构 oracle中的进程共分为三类:用户进程、服务进程、后台进程。其中后台进程伴随实例的启动而启动,他们主要是维护数据库的稳定,相当于一个企业中的管理者及内部服务人员。他们并不会直接给用户提供服务。 下面说说oracle 的比较常见的后台进程,不是所有的进程。(dbwn和lgwr较重要,前面已做了了解,在此不再展开)其中dbwn,arcn可以设置数据库启动时的数量。这些进程在系统中可以不止一个。 (1)dbwn 数据库写进程:数据库缓冲区的治理进程。(请参考上面的“数据库缓冲区缓存&数据库写入器”中的描述) 在它的治理下,数据库缓冲区中总保持有一定数量的自由缓冲块,以确保用户进程总能找到供其使用的自由缓冲块。 (2)lgwr 日志文件写进程:(请参考上面的“日志缓冲区&日志写入器”中的描述) 是日志缓冲区的治理进程,负责把日志缓冲区中的日志项写入磁盘中的日志文件上。每个实例只有一个lgwr进程。 (3)smon(system monitor):安装和打开数据库,负责完成自动实例恢复和回收分类(sort)表空间。 作用: a.负责实例恢复,前滚(roll forward)恢复到实例关闭的状态,使用最后一次检查点后的日志进程重做。这时包括提交和未提交的事务。打开数据库,进行回滚(roll back):回滚未提交的事务。(oracle承诺commit之后数据不会丢失,现在我们可以大致的了解是如何实现这个承诺,以及在数据的安全性和数据库性能之间的平衡选择。) b.负责清理临时段,以释放空间 触发条件:定期被唤醒或者被其他事务主动唤醒。 (4)pmon(process monitor):进程监视器,主要监视服务器进程。前面提到过,专有服务器体系模式下,用户进程和服务器进程是一对一的关系,如果某个会话发生异常,pmon会销毁对应的服务器进程,回滚未提交的事务,并回收会话专有的pga内存区域。 作用: a.发现用户进程异常终止,并进行清理。释放占用资源。(清理异常终止用户使用的锁) b.向监听程序动态的注册实例。 触发条件:定时被唤醒,其他进程也会主动唤醒它。 (5)ckpt(checkpoint process):ckpt负责发起检查点信号,手动设置检查点的语法:
1 alter system checkpoint; 检查点可强制dbwn写入脏缓冲区,当数据库崩溃后,由于大量脏缓冲区未写入数据文件,在重新启动时,需要由smon进行实例恢复,实例恢复需要提取和应用重做日志记录,提取的位置就是从上次检查点发起的位置开始的(检查点之前的数据已经被强制写入到数据文件中去了),这个位置称为rba(redo byte address),ckpt会不断将这个位置更新到控制文件中去(以确定实例恢复需要从哪儿开始提取日志记录)。 触发条件:日志切换(log switch)会触发检查点。 (6)mmon(manageability monitor)–awr主要的进程 数据库的自我监视和自我调整的支持进程。实例在运行中,会收集大量有关实例活动和性能的统计数据,这些数据会收集到sga中,mmon定期从sga中捕获这些统计数据,并将其写入到数据字典中,便于后续对这些快照进行分析。(默认情况,mmon每隔一个小时收集一次快照) 作用: a.收集awr必须的统计数据,把统计数据写入磁盘。10g中保存在sysaux表空间中。 b.生成server–generated报警 触发条件:每小时把shared pool中的统计信息写入磁盘,或者shared pool占用超过15%。 (7)arcn(archiver process) 归档进程,这个进程是可选的,如果数据库配置为归档模式,这个进程就是必须的。所谓归档,就是将重做日志文件永久保存(
生产库一般都会配置为归档模式)到归档日志文件中。归档日志文件和重做日志文件作用是一样的,只不过重做日志文件会不断被重写,而归档日志文件则保留了关于数据更改的完整的历史记录。 作用:发生日志切换时把写满的联机日志文件拷贝到归档目录中。 触发条件:日志切换时被lgwr唤醒。 设置:log_archive_max_processes可以设置oracle启动的时候arcn的个数。 (8)manageability monitor light(mmnl):轻量级的mmon (9)memory manager(mman):自动内容管理 作用:每分钟都检查awr性能信息,并根据这些信息来决定sga组件最佳分布。 设置:statistics_level:统计级别 sga_target:sga总大小 (10)job queue coordinator(cjq0):数据库定时任务 (11)recover writer(rvwr):作用是为flashback database提供日志记录。把数据块的前镜像写入日志。 (12)change tarcking writer(ctwr): 作用是跟踪数据块的变化,把数据块地址记录到 change_tracking file文件中。rman的增量备份将使用这个文件来确定那些数据块发生了变化,并进行备份。 (13)lckn 封锁进程:用于并行服务器系统,主要完成实例之间的封锁
4.总结: 至此,oracle基础的内存结构和进程结构我们已大概了解,来看下完成的进程和内存的交互情况,可以根据前面的理解将整个交互流程串联一下。
二、oracle数据库存储结构 这一部分主要参考(抄袭): 根据上文描述,oracle数据库服务,由实例+数据库构成。上面讲了实例,下面开始介绍数据库对象(存储结构——逻辑结构和物理结构) oracle数据库的存储结构可以分为逻辑存储结构和物理存储结构,对于这两种存储结构,oracle是分别进行管理的。 逻辑存储结构:oracle内部的
组织和管理数据的方式。 物理存储结构:oracle外部(操作系统)组织和管理数据的方式——真实
存储数据的地方。
1.逻辑存储结构: oracle在逻辑上将保存的数据划分为一个个小单元来进行存储和维护,更高一级的逻辑存储结构都是由这些基本的小单元组成的。 逻辑结构类型按照尺寸
从小到大分可分为:
块(block)–>区(extent)–>段(segment)–>表空间(tablespace)。 图示如下: 我们可以用下面的比喻来描述逻辑结构关系:
块 :一张张白纸 —> 区:白纸组成的本子—> 段:多个本子放到一个文件袋中—> 表空间:文件柜(存放多个文件袋) 下面对每一个概念具体介绍: (1)块(block):
oracle用来管理存储的最小单元,也是最小的逻辑存储结构。oracle数据库在进行输入输出时,都是以块为单位进行读写操作的。块的大小由参数
db_block_size设置,不同的oracle版本db_block_size的默认值是不同的。我们建议
数据块的尺寸为操作系统块尺寸的整数倍(1、2、4等)。另外,
块的大小是在创建数据库的时候决定的,之后不能修改。当然,oracle同时也
支持不同的表空间拥有不同的数据块尺寸。下面,我们对块的结构进行一些介绍。 1)块的头部信息区: 块头:包含块的一般属性信息,如,块的物理地址、块所属的段的类型 表目录:如果块中存储的数据是表数据, 则在表目录中保存块中所包含的表的相关信息 行目录:行记录的相关信息 如,rowid 2)块的存储区:主要包含空闲空间和已经使用的空间。oracle主要是通过下面的两个参数对这部分空间进行管理的
- pctfree参数:指定块中必须保留的最小空闲空间比例。当块中的空闲存储空间减少到pctfree所设置的比例后,oracle将块标记为不可用状态,新的数据行将不能被加入到这个块。
- pctused参数:制定一个百分比,当块中已经使用的存储空间降低到这个百分比之下时,这个块才被重新标记为可用状态。
注意:以上两个参数(pctfree、pctused)既
可以在表空间级别进行设置,
也可以在段级别进行设置。段级别的设置优先级更高。 (2)区(extent): 比块高一级的逻辑存储结构,
由连续的块组成,它是
oracle在进行存储空间的分配和回收的最小单位(区是磁盘分配的最小单位)。在创建具有独立段结构的数据库对象时,例如表、索引等,oracle会为数据库对象创建一个数据段,并为数据段分配一个‘初始区’。后续区的分配方式,则根据表的空间管理办法不同,而采用不同的分配方式,例如autoextent,uniform size 或者在创建表或表空间时设置default storage 子句。另外,用户还能够通过执行下面的命令来回收表、索引等对象中未使用的区:
1 -- 相关表:dba_extents 、user_extents 2 select * from dba_extents; 3 select * from user_extents; 4 5 --回收表、索引等对象中未使用的区 6 alter table table_name deallocate unused;
(3)段(segment): 由多个区组成,这些区可以是连续的,也可以是不连续的。当用户在数据库中创建各种具有实际存储结构的对象时(保存有数据的对象),比如表、索引等,oracle将为这些对象创建“段”。
一般一个对象只拥有一个段。在创建段时,可以为它指定pctfree、pctused等参数来控制其中的块的存储空间管理方式,也可以为它指定initial、next、pctincrease等存储参数,以指定其中区的分配方式。如果
没有为段指定这些参数,段将自动继承表空间的相应参数。不同类型的数据库对象拥有不同类型的段:
- 数据段:保存用户的数据(表中的记录)。每个表都有一个对应的数据段,其名称和数据表的名字相同
- 索引段:用来存储系统、用户的索引信息(索引中的索引条目)
- 临时段:在执行查询等操作时,oracle可能会需要使用到一些临时存储空间,用于临时保存解析过的查询语句以及在排序过程中产生的临时数据,如:order by语句的排序以及一些汇总等。
- 回滚段:用来存储用户数据修改前的值,回滚段与事务是一对多的关系,一个事务只能使用一个回滚段,而一个回滚段可存放一个或多个事务的回退数据。
概括来说:每建立一张表,往往对应一个段,如果是分区表,那么各个分区又独立成段。在表上建一个索引,则又会有一个对应的索引段。
1 --相关表:dba_segments 、 user_segments 2 select * from dba_segments; 3 select * from user_segments;
(4)表空间(tablespace): 最高级的逻辑存储结构,
一个oracle数据库是由多个表空间组成的, 但一个表空间只隶属于一个数据库,一个表空间可以有多数据文件,但是一个数据文件只能属于一个表空间。一个表空间就是一片磁盘区域,他由一个或者多个磁盘文件组成,一个表空间可以容纳许多表、索引或者簇等。每个表空间有一个预制的磁盘区域称为初始区间(initial extent)用完这个区间后再用下一个,直到用完表空间,这时候需要对表空间进行扩展,增加数据文件或者扩大已经存在的数据文件。在创建数据库时会自动创建一些默认的表空间,例如 system表空间,sysaux表空间等。通过使用表空间,oracle将所有相关的逻辑结构和对象组合在一起。我们
可以在表空间级别指定存储参数,也可以在段级别指定。下面我们列出常见的表空间,和他们所存储的信息:
- 数据表空间:或称为用户表空间,用于存储用户数据的普通表空间。
- 系统表空间:默认的表空间,用于保存数据字典(一组保存数据库自身信息的内部系统表和视图,及用于oracle内部使用的其他一些对象),保存所有的pl/sql程序的源代码和解析代码,包括存储过程和函数、包、数据库触发器等,保存数据库对象(表、视图、序列)的定义。
- 回滚表空间:用于存放回滚段,每个实例最多只能使用一个撤销表空间。undo表空间的4个常见作用:
1)事务回滚,我们对数据进行dml操作的时候,如果撤销修改,就会通过undo表空间记录的修改前数据把数据恢复到修改前。有些存储过程中通过exception捕捉异常的时候经常会有一句rollback,也是这个作用,对当前事务的数据操作进行回滚恢复。 2)数据库恢复,数据库异常关闭,重新启动的时候依据undo表空间的记录回退未提交的事务,将数据库恢复。 3)
读一致性,在一个会话操作数据未提交的时候,通过undo表空间保证其他人访问的数据的一致性(就是未修改的样子)。 4)闪回查询,这是个很有趣的功能。可以查看某个时间点时候的数据,经常,算了,也不经常,主要用于误操作、误删数据等的恢复。 综上所述,这些东西日常来说基本都不用管。
- 临时表空间:存储sql执行过程中产生的临时数据。创建oracle数据库的时候可以设置一个叫sort_area_size的参数,默认值为65536,排序的时候会首先使用这部分内存,如果不足就会使用临时表空间。
表空间的模式,也可以称为状态,可以设置表空间的online(联机)或者offline(脱机),read/write(读/写) 或者 read-only(只读) 表空间可以自动或手动脱机。例如,您可以将表空间脱机,以进行维护或备份与恢复。数据库在遇到某些错误时会自动将一个表空间脱机,比如数据库写进程 (dbwn)多次试图写入数据文件但均遭遇失败时。当用户试图访问一个脱机表空间中的表时,将收到一个错误。
※安装oracle时,表空间的一些默认配置: 1)oracle database 11g r2在用dbca数据库管理助手创建数据库的时候,默认会创建三个永久表空间(system、sysaux、users),一个临时表空间(temp),一个撤销表空间(undotbs1)。 2)oracle数据库有几个缺省表空间,其中system和sysaux 表空间是一个oracle数据库必须有的。系统
必须表空间是
system,sysaux,temp,undotbs1
※各类表空间的操作方法,以及实践: 1)查询表空间
1 select * from dba_tablespaces; 2)创建数据表空间
1 create tablespace "ts_test" --表空间名weixin 2 logging --启动重做日志 3 datafile 'd:\app\oradata\orcl\ts_test.dbf' --指定对应的数据文件,可以一个或者多个 4 size 512m --数据文件大小 5 autoextend on --数据文件自动扩展 6 next 1024k --一次扩展的大小 7 maxsize unlimited --数据文件最大容量:无限 8 extent management local --表空间本地管理 9 segment space management auto ; --存储管理方式,auto为自动方式
3)创建临时表空间
1 create temporary tablespace tmp_ts_test 2 tempfile 'd:\app\oradata\orcl\tmp_ts_test.dbf' 3 size 100m;
4)回滚段表空间
1 create undo tablespace undo_ts_test 2 datafile 'd:\app\oradata\orclundo_ts_test.dbf' 3 size 100m;
5)新建用户,并将先前建的表空间 ts_test 和临时表空间 tmp_ts_test 作为testuser用户的默认使用空间。
1 --创建新用户,同时指定表空间和临时表空间 2 create user testuser --创建用户testuser 3 profile "default" --忽略对profile中的一些资源限制(什么鬼,不明白) 4 identified by "pwd123456" --密码为weixin 5 default tablespace ts_test --默认表空间ts_test,即数据默认存此表空间 6 temporary tablespace tmp_ts_test --临时表空间 7 quota 500m on ts_test --用户在表空间中的限额 8 account unlock; --解锁用户 9 10 --通常建完用户后会给用户授予一些基本的权限 11 grant connect, resource to testuser; 12 13 --或者直接给用户赋予dba权限(只是测试,生产请不要这么做) 14 --with admin option 表示在获得权限的同时也获得了将这个权限授予其他用户的能力。 15 grant "dba" to "testuser" with admin option;
oracle的安全策略方面默认一个用户的密码有效期为180天,我们可以直接把这个有效期调成永久。
1 alter profile default limit password_life_time unlimited; 6)如果表空间不足,可以有两种方法: 第一种,增加数据文件:
1 alter tablespace ts_test(表空间名) 2 add datafile '......'(数据文件全路径名) 3 size 1000m;
第二种,把表空间设置为自动扩展:
1 alter database datafile '.......'(数据文件全路径名) 2 autoextend on; (在创建表空间时,就可以加上这个关键字,表示该表空间自动扩展)
7)删除表空间
1 drop tablespace ts_test 2 including contents and datafile;
如果表空间有数据,不增加 including contents 将无法删除成功,增加 and datafiles 关键字在linux 及 unix 下可自动删除数据文件,而在windows 环境下需要手动删除 8)undo 表空间和 temp 表空间在数据库建好是必然已经创建好了,不过,它们都可以新建,并且用户都可以指定新建的空间。 9)oracle 可以为不同的用户指定不同的临时表空间,而且可以为同一用户的不同session 设置不同的临时表空间(临时表空间组),从而减缓io 竞争。
2. oracle物理存储结构: oracle数据库逻辑上由一个或多个表空间组成,每个表空间在物理上由一个或多个数据文件组成,而每个数据文件由数据块构成的。所以,
逻辑上数据存放在表空间中,而物理上存储在表空间所对应的数据文件中。我们可以用这张图来描述数据文件和表空间的关系。 或者用下面这张图理解下: (1)构成oracle数据库物的物理文件组织结构:
※基础文件: 1)控制文件: 控制文件虽小,但作用重大,它存放数据库的基本信息。它包含指向数据库其余部分的指针(包括重做日志文件,数据文件,归档日志文件等的位置),存储重要的序列号和时间戳,存储rman备份的详细信息。控制文件一旦受损,那实例会立马终止,一
般对控制文件的保护采用多路复用机制,就是冗余多份在不同物理位置。 2)重做日志文件 重做日志文件的作用为:存放对数据的改变,重做日志按时间顺序存储应用于数据库的一连串的变更向量(包含联机重做日志文件和归档日志文件)。由smon在数据库启动时自动执行的实例恢复和磁盘损坏所要求的提取备份恢复都会应用到重做日志进行相应的数据恢复 重做日志文件
也建议进行多路复用,一个数据库至少要有两组重做日志文件。一组供lgwr进行写入,日志文件是固定大小,业务高峰期会很快写满,写满之后会切换到第二组上,在配置为归档模式的数据库中,这时由归档进程(arcn)开始将第一组的内容进行归档备份,如此循环地进行写入和归档。需要注意的是,在归档进程还未对当前组的日志归档完毕前,是不允许lgwr对其进行重写的。 3)数据文件 数据文件存储着实际的数据,它是具体的存储数据的物理文件,是一个物理概念。dbwn会将数据库缓冲区中的内容写入到这类文件中去,数据文件的大小和数量是不受限制的。oracle从10g开始,
创建一个数据库至少需要两个数据文件,一个用于system表空间,该表空间用来存储数据字典;一个用于sysaux表空间,这个表空间用来存储一些数据字典的辅助数据。 数据文件由一个个的oracle块组成,这是oracle的i/o基础单元,与操作系统块是不同的概念,oracle块要比操作系统块大,这当然有出于性能的一些考虑,但我们考虑这样一种情况,当用户使用操作系统命令进行数据文件的备份的时候(假设1个oracle块=8个操作系统块),已经复制了4个操作系统块,然后cpu被dbwn抢占了,dbwn又重新对这个oracle块进行了更新,这时,当复制命令又得到了cpu时间去复制剩余的4个块的时候,就造成了整个oracle块的数据不一致,所以,这也是在执行这种备份(用户自行备份)的时候,需要做一些额外处理,比如将表空间置为备份模式的原因。当然,使用rman是不存在这样的问题的,rman的备份机制是肯定可以得到数据一致的块的。(这块内容作了解即可) 对于数据文件的保护,一般可进行定期备份,或者使用raid也可以。
※外部文件: 所谓外部文件,意味着这些文件从严格意义上来讲并不属于oracle数据库的一部分。 1)实例参数文件 这个文件存储了数据库所需的一些参数设置,比如各个内存区域的大小,可允许的最大进程数,最大会话数,控制文件的位置,数据库的名称等等,参数文件也是
实例启动时首先要加载的文件。 2)口令文件 一般称为外部口令文件。
一般的用户名和口令是存放在数据字典中,不会存放在这个文件中。在一些特殊场景下,比如实例还未启动,这时,我可能需要以管理员的身份登入系统去执行一些恢复或者启动操作,然而此时,数据字典由于实例还没启动是不存在的,这时就需要外部口令文件进行用户身份的验证。 3)归档日志文件 arcn将联机重做日志文件会备份归档到这类文件中去,归档日志文件保留了数据更改的完整历史信息。
三、oracle数据库的启动流程 这一部分主要参考(抄袭): oracle 的启动需要经历四个状态,shutdown 、nomount 、mount 、open、
1.数据库流程详解 (1)startup nomount 启动实例(不加载数据库),这个过程,会读取配置文件(spfile / pfile)文件的相关参数来创建实例,也就是一系列的进程,启动完成后实例是 started 状态。 (2)alter database mount; 加载(关联)数据库,这个过程的时候,实例读取控制文件,关联到对应的数据库,此时实例为mounted状态。 (3)alter database open; 打开数据库,实例连接到数据文件,这个时候其他用户就可以访问到数据库进行读写操作了,此时实例的状态是open。 所以,我们打开的过程中实例的状态就是:
deaded(idle)>>started >> mounted >> open。
2.数据库启动流程实践 一般一台机子上都会建立多个数据库的,那么怎么启动自己想启动的那个实例呢?答案是:通过oracle_sid控制,oracle_sid是数据库在操作系统的一个唯一标识,在演示数据库启动流程前,我们先设定oracle_sid,然后再启动实例。 (1)准备工作如下: 1)设定要启动的数据库,可以不设,使用安装时默认启动的那个数据库即可
1 c:\users\anand>set oracle_sid=orcl
2)和数据库建立连接(其实一般这样就可以使用了)
1 c:\users\anand>sqlplus / as sysdba 2 sql*plus: release 11.2.0.1.0 production on 星期六 6月 2 10:58:17 2018 3 copyright (c) 1982, 2010, oracle. all rights reserved. 4 连接到: 5 oracle database 11g enterprise edition release 11.2.0.1.0 - 64bit production 6 with the partitioning, olap, data mining and real application testing options
(2)测试数据库启动流程 1)启动实例(不加载数据库)
1 sql> startup nomount 2 oracle 例程已经启动。 3 4 total system global area 1068937216 bytes 5 fixed size 2182592 bytes 6 variable size 624951872 bytes 7 database buffers 436207616 bytes 8 redo buffers 5595136 bytes
2)加载(关联)数据库
1 sql> alter database mount; 2 3 数据库已更改。
3)打开数据库
1 sql> alter database open; 2 3 数据库已更改。
4)验证
1 sql> select status from v$instance; 2 3 status 4 ------------ 5 open
四、oracle 的用户、schema、数据库、表空间、数据文件的相互关系 这一部分主要参考(抄袭):
在进入抽象的概念之前,可以先看下网上的这段比喻: “我们可以把database(这里应该指的是某一个sid对应的数据库)看作是一个大仓库,仓库分了很多很多的房间,schema就是其中的房间,一个schema代表一个房间,table可以看作是每个schema中的床,table(床)被放入每个房间中,不能放置在房间之外,那岂不是晚上睡觉无家可归了,然后床上可以放置很多物品,就好比 table上可以放置很多列和行一样,数据库中存储数据的基本单元是table,现实中每个仓库放置物品的基本单位就是床, user就是每个schema的主人,(所以schema包含的是object,而不是user),user和schema是一一对应的,每个user在没有特别指定下只能使用自己schema(房间)的东西,如果一个user想使用其他schema(房间)的东西,那就要看那个schema(房间)的user(主人)有没有给你这个权限了,或者看这个仓库的老大(dba)有没有给你这个权限了。换句话说,如果你是某个仓库的主人,那么这个仓库的使用权和仓库中的所有东西都是你的(包括房间),你有完全的操作权,可以扔掉不用的东西从每个房间,也可以放置一些有用的东西到某一个房间,你还可以给每个user分配具体的权限,也就是他到某一个房间能做些什么,是只能看(read-only),还是可以像主人一样有所有的控制权(r/w),这个就要看这个user所对应的角色role了。”
这些oracle数据库中具体的概念在前面已经介绍过了,下面再简述一下: (1)数据库: oracle数据库是数据的物理存储。这就包括(数据文件ora或者dbf、控制文件、联机日志、参数文件)。其实oracle数据库的概念和其它数据库不一样,这里的数据库是一个操作系统只有一个库。可以看作是oracle就只有一个大数据库。 (2)实例: 一个oracle实例(oracle instance)有一系列的后台进程(backguound processes)和内存结构(memory structures)组成。
一个数据库可以有n个实例。
数据库和实例的关系: oracle实例与oracle数据库,这个是比较混淆的一个概念,在很多观念下,包括我以前也会认为一个实例等价于一个数据库,其实这个应该说是在
大部分情况下可以认为:一个实例对应一个数据库, 实例是一个instance,而数据是对外屏蔽的一些转换后文件组合(学习过第四代数据库就知道,如果你做过裸机文件也会明白原理),数据库不是对外直接开放的,开放的规则是通过实例(instance),instance是一段内存,这个内存中包含很多个不同的版块(主体上的分就是sga和pga了), 我们一切操作都是交给实例的,而不是直接操作数据库文件系统,为什么要有中间这个过程,oracle考虑到:安全、缓冲、效率、扩展性等问题;而为什么是大部分情况下这样说, 因为oracle还有集群的概念,对于oracle rac真正集群使用后你会更加深刻认识实例和数据库之间的关系,它使用多个分布于不同主机上的实例,对同一个裸机文件系统上的数据库进行操作,所以此时实例和数据库就不是一对一了,而是多对一,但是一个实例只能用一个数据库这是肯定的。
(3)用户(user)
用户是在实例下建立的。不同实例可以建相同名字的用户。 具体的创建用户的方法是这样的(再写一遍):
1 --创建新用户,同时指定表空间和临时表空间(建议创建的时候指明表空间名) 2 create user testuser --创建用户testuser 3 profile "default" --忽略对profile中的一些资源限制(什么鬼,不明白) 4 identified by "pwd123456" --密码为weixin 5 default tablespace ts_test --默认表空间ts_test,即数据默认存此表空间 6 temporary tablespace tmp_ts_test --临时表空间 7 quota 500m on ts_test --用户在表空间中的限额 8 account unlock; --解锁用户
※关于profile的说明(使用profile文件实现用户口令限制与资源限制) proflie是口令限制,资源限制的命名集合.建立oracle数据库时,oracle会自动建立名为default的profile,初始化的default没有进行任何口令和资源限制.使用profile有以下一些主要事项: a,建立profile时,如果只设置了部分口令或资源限制选项,其他选项会自动使用默认值(default的相应选项) b,建立用户时,如果不指定profile选项,oracle会自动将default分配给相应的数据库用户. c,一个用户只能分配一个profile.如果要同时管理用户的口令和资源,那么在建立profile时应该同时指定口令和资源选项. d,使用profile管理口令时,口令管理选项总是处于被激活状态,但如果使用profile管理资源,必须要激活资源限制.
※关于profile使用的实践 1)查看当前存在的profile文件
1 select distinct profile from dba_profiles; 2 --查看指定profile文件中各资源的限制情况: 3 select resource_name,limit from dba_profiles where profile='default';
2)修改现在profile文件中资源选项:
1 alter profile default limit failed_login_attempts 1 password_lock_time 3;
3)创建一个新的profile文件:
1 create profile lock_accout limit failed_login_attempts 3 password_lock_time 10;
4)让用户使用新的profile文件:
1 alter user testuser profile lock_accout;
5)查看用户当前使用的profile文件
select username,profile from dba_users;
6)使用profile文件限制用户对资源的使用;
1 --必须先激活资源限制: 2 alter system set resource_limit=true scope=memory; 3 --对资源限制做修改: 4 alter profile lock_accout limit cpu_per_session 5000;
7)删除profile
1 drop profile lock_accout;
8)删除profile并将使用当前profile的用户profile改为default
1 drop profile lock_accout cascade;
9)以下列出所有profile相关参数内容以便于参考:
failed_login_attempts:用于指定联系登陆的最大失败次数. password_lock_time:用于指定帐户被锁定的天数. password_life_time:用于指定口令有效期 password_grace_time:用于指定口令宽限期. password_reuse_time:用于指定口令可重用时间. password_reuse_max;用于指定在重用口令之前口令需要改变的次数. password_verify_function;是否校验口令(校验将值改为verify_function) cpu_per_session:用于指定每个会话可以占用的最大cpu时间. logical_reads_per_sesson:用于指定会话的最大逻辑读取次数. private_sga:用于指定会话在共享池中可以分配的最大总计私有空间.需要注意,该选项只使用与共享服务器模式. composite_limit:用于指定会话的总计资源消耗(单位:服务单元). cpu_per_call:限制每次调用(解析,执行或提取数据)可占用的最大cpu时间(单位:百分之一秒) logical_reads_per_call:用于限制每次调用的最大逻辑i/o次数. sessions_per_user:用于指定每个用户的最大并发会话个数. connect_time:用于指定会话的最大连接时间. idle_time:用于指定会话的最大空闲时间.
(4)schema:
在oracle中,一般一个用户就对应一个schema,该用户的schema名等于用户名,并作为该用户缺省schema,用户是不能创建schema的,schema在创建用户的时候创建,并可以指定用户的各种表空间(这点与postgresql是不同,postgresql是可以创建schema并指派给某个用户)。当前连接到数据库上的用户创建的所有数据库对象默认都属于这个schema(在不指明schema的情况下),比如若用户scott连接到数据库,然后create table test(id int not null)创建表,那么这个表被创建在了scott这个schema中;但若这样create table testuser.test(id int not null)的话,这个表被创建在了testuser这个schema中,当然前提是权限允许(即testuser用户给scott用户在其schema下创建数据表的权限)。由此来看,schema是一个逻辑概念。 但一定要注意一点:
schema并不是在创建user时就创建的,而是在该用户创建了第一个对象之后才将schema真正创建的,只有user下存在对象,他对应的schema才会存在,如果user下不存在任何对象了,schema也就不存在了; (5)表空间: 表空间是一个用来管理数据存储
逻辑概念,表空间只是和数据文件(ora或者dbf文件)发生关系,数据文件是物理的,
一个表空间可以包含多个数据文件,而一个数据文件只能隶属一个表空间。 (6)数据文件(dbf、ora): 数据文件是数据库的
物理存储单位。数据库的数据在逻辑上是存储在表空间中的,但真正落地是在某一个或者多个数据文件中。而一个表空间可以由一个或多个数据文件组成,一个数据文件只能属于一个表空间。一旦数据文件被加入到某个表空间后,就不能删除这个文件,如果要删除某个数据文件,只能删除其所属于的表空间才行。
表的数据,是由用户放入某一个表空间的,而这个表空间会随机把这些表数据放到一个或者多个数据文件中。 由于oracle的数据库不是普通的概念,oracle是有用户和表空间对数据进行管理和存放的。但是表不是有表空间去查询的,而是由用户去查的。因为不同用户可以在同一个表空间建立同一个名字的表!这里区分就是用户了!
下图也许有助于理解上述名称之间的关系: 参考: https://blog.csdn.net/huay_li/article/details/80575538 https://blog.csdn.net/ochangwen/article/details/51171992