++ 逻辑结构(数据块, 区, 段和表空间)作为构建基础, 存储结构+数据块进程 等于 oracle实例
++ oracle将数据库用户和物理结构数据文件分开(用户通过逻辑结构,逻辑结构管理物理结构)
-- 逻辑结构: 表空间, 段, 区, 块
-- 数据库中的一组相关的逻辑对象称为一个模式(数据库对象与模式区分开)
-- 数据块(数据存储的基础逻辑结构, 有多个字节组成)
通过数据块分配数据库空间, 数据块由多个磁盘块(一个磁盘块通常为4KB, 32KB)组成(数据块大小是磁盘块大小的倍数)
CUR操作以数据块为单位提取数据(检索数据大小小于数据块大小, 也会至少读取包含数据的整个数据块)
init.ora初始化文件 DB_BLOCK_SIZE指定数据块大小(2~32KB), 可以配置多个数据块大小(用于在多个不同数据块的数据库之间传输表空间)
行数据小且访问随机, 选择较小的数据块尺寸. 如果行数据小但是连续或者行数据大使用较大的数据块尺寸, Oracle建议8KB
数据库块=行数据(表,索引数据)+可用空间(为扩充行数据,插入新数据保留的空间)+系统开销+首部空间
通过块转储可以查看数据块存储的数据
select header_file, header_block from dba_segments where owner = '数据库用户名' and segment_name = '数据库对象名';
块转储: alter system dump datafile [header_file] block [header_block];
读取转储数据: select name from sys.obj$ where obj# = '转储obj#值';
-- 区(空间分配单元,多个相邻数据块组成)
创建数据库对象时会创建初始区, 并指定下一个区的空间量. 数据库对象删除之后才会释放对于的区到可用空间池
-- 段(由构成数据块对象的多个区组成一个段)
为一个数据库对象分配的所有区为一个段, TEST表分配的空间称为TEST段, 创建索引有对应的索引段, 分类和事务有临时段, 存储撤销信息的撤销段
一个段的所有区都写满数据, 分配的新的区不一定连续
-- 表空间(多个段, 包括表数据和索引数据)
Oracle数据库分为1~n个表空间, 一个表空间有1~n个数据文件组成, 相关联的表存储在同一个表空间中
默认表空间: System表空间(数据字典), Sysaux表空间, 撤销表空间, 临时表空间, 默认参数表空间(Oracle初始化时创建System和Sysaux, 不可删除和重命名)
一个表空间的数据文件可能遍布在多个磁盘中, 逻辑卷管理器不需要建立太多的表空间, 索引和数据文件不用建立不同的表空间
可以以表空间作为备份/恢复单元, 不同的表空间可以使用不同的数据块尺寸(优化磁盘IO, 不同尺寸不同的池优化数据高速缓存, 表空间的传送)
一个数据文件只属于一个表空间
表空间通过位图(位为单位保留一个或一组块的空间信息的图)跟踪数据块的可用或已用状态
数据库对象增加数据时以区为单位分配新的空间. Oracle选择第一个可用数据文件并通过位图查找是否有可用的数据块(整个过程不会使用数据字典)
Oracle默认的表空间为小文件表空间(一个表空间有多个数据文件), 以小文件表空间的方式创建System和Sysaux表空间
临时表空间只保存用户会话期间的数据
撤销表空间包含撤销记录, 用于回滚和撤销
只读表空间, 可以将任何普通的表空间转换为只读表空间
-- Oracle数据库(数据库文件+系统文件), Oracle实例(存储结构+)
++ 物理数据库结构
-- 数据文件(存储表, 索引数据)
一个数据文件对应一个数据库, 1~n个数据文件组成表空间的实体
Oracle 8i中石油OMF(Oracle Managed File文件管理)只需要处理数据库对象, 不用操作数据文件. 适用于数据量小的数据库
当表消耗完初始分配的空间大小, 必须给该表空间增加一个新数据文件扩大表空间
-- 控制文件(记录数据库结构更改信息, 管理数据库状态)
Oracle在初始化数据库时创建控制文件及其多个副本(一般三个, 修改控制文件的同时修改副本文件)
如果不访问最新的控制文件, 无法恢复数据
只有Oracle进程才能向控制文件中连续不断的更新数据
控制文件包括: 重做日志文件和数据文件的位置, 当前日志序号, 备份集信息, 检查点信息(使Oracle确定从重做日志文件中返回多少以便恢复数据)
控制文件查询: select status, name, is_recovery_dest_file(是否创建在闪回恢复区) from V$CONTROLFILE;
-- 重做日志文件(记录表数据更改信息)
可以通过重做日志文件对数据库最新更改信息进行恢复数据库, 当前用来记录数据库更改的称为联机重做数据库文件(当前的重做日志文件)(文件可以复制,归档重做日志)
Oracle提交的数据会先写入到重做日志文件中, 如果故障导致无法写入到数据文件中. 在恢复的时候重做, 保证任何时候不会丢失已提交的数据
重做日志文件由重组记录组成, 一条重组记录对应一个数据块的修改. 一个事务可以对应多个重做记录
重做记录日志会先保存在重做日志缓冲中(内存), 再写入到文件中
重做日志文件中保存: 事务开始时间, 事务名, 被更改数据库对象的名称, 前影像, 后影像, 提交指示器(是否完成和完成时间)
系统崩溃时, 所有的事务都会通过重做日志文件写入到磁盘中, 有开始项和提交项的都会重做(后影像记录写入到数据库), 只有开始项的不完全的事务通过撤销表空间中的前影像撤回
Oracle至少有两个重做日志组, 每一个重做日志组至少一个重做日志文件
数据库会重写重做日志文件, 可以对写满的日志文件进行归档, 保留完整的数据块更改记录
采用多路复用重做日志文件(多个文件保证不丢失数据更改信息)
-- 初始化文件(init.ora), 网络管理文件, 预警日志文件, 跟踪文件, 备份文件和密码文件
SPFILE(服务器参数文件)可以动态的记录动态初始化参数的值进行修改, 通过V$SPPAPAMETER视图查看
预警日志文件会记录Oracle实例运行时发生的错误,警告. alert_数据库名.log
ADR目录下保存预警日志文件和跟踪文件
备份文件+归档重做日志文件(恢复点)恢复数据
++ Oracle进程
-- 包括持续的(强制在Oracle启动的时候运行的)和特定情况使用的进程(复制数据库)
-- 用户进程: 连接用户和数据库实例
用户通过用户界面通过用户进程与服务器进行通信, 通过服务器进程返回SQL执行操作结果
一个会话会创建一个用户进程用于连接服务器
-- Oracle进程: 服务器进程和后台进程, 实际工作操作
服务器进程是为用户进程服务而创建
用户连接服务器会创建一个单独的服务器进程, 再用户请求时, 为该用户创建服务器进程检查SQL语法, 执行SQL语句. 并将结果返回给用户
服务器进程配置类型
专用服务器配置: 每个用户对应一个服务器进程
共享服务器配置: 用户通过调度程序使用一个共享的服务器进程. 节省内存开销. 通过共享服务器连接池可以重用超时连接
数据库驻留连接池: 建立专用服务器进程池, 从中获取服务器进程
-- 后台进程
启动数据库实例时由Oracle自动创建, 数据库关闭时终止
++ 数据库写入器(DBWn)
当数据库缓冲区可用空间下降, DBWn会将更改的数据从数据库缓冲区中写入到数据文件中
触发条件: 每隔3秒, 或者没有可重用的数据块缓冲区, 或者数据库发布检查点时
最大使用20个数据库写入器, 如果配置文件DB_WRITER_PROCESSES没有指定数据块写入器数量, 则通过CPU确定DBWn个数
++ 日志写入器(LGWR)
将重做日志缓冲区内容写入到联机重做日志缓冲区中(多路复用会写入到所有可用副本), 在数据修改时会将数据修改信息保存到重做日志缓冲区中
触发条件: 每隔3秒, 或者重做日志缓冲区写满三分之一, 或者日志缓冲区大小超过1M, 或者数据库写入器通知日志写入器写入
数据库写入器写入数据之前必须将对应的重做日志信息写入到联机重做日志文件中, 才能写入到数据文件中(写前协议)
每次事务提交之后会执行重做日志写入操作, 事务提交会在重做日志文件中写入事务记录, 并将其和对应相关的数据修改记录写入到重做记录日志(标志事务提交的关键)
每个已提交的事务会分配一个对应的SCN, 日志写入器会写入到重做日志文件中. 数据库恢复时通过SCN恢复. 在数据还没有写入到磁盘, 但是日志写入器指示事务成功, 称之为快速提交机制
重做日志文件可能包括已提交和未提交的事务记录
++ 检查点(CKPT)
通知DBWn写入数据到数据文件, 并更新所有数据文件的头记录检查点的详细值(每3秒将DBWn写入完成率记录到数据文件头和控制文件中)
目的: 同步数据库缓冲区与数据库数据文件中的数据, 并更新数据文件头信息和控制文件记录检查点信息(包括执行时间)
1.把重做日志缓冲区的内容刷新到重做日志文件
2.把检查点记录写入到重做日志文件
3.把数据库缓存区内容写入到数据文件
4.更新数据文件和控制文件
++ 进程监控器(PMON)
PMON进程采用轮询的方式定期查询是否有进程失败, 对用户异常断开等导致的用户进程失败, 对用户进程, 服务器进程和锁资源等进行释放
在共享服务器模式时是重新启动失败的服务进程
PMON自动执行动态服务登记, 创建一个新的数据库实例时, 会通过监听器登记该实例信息
在listener没有启动时, PMON无法进行服务注册, 会尝试连接listener. listener在启动60秒之后才能进行服务注册
++ 系统监控器(SMON)
在Oracle运行崩溃后进行重启恢复, 恢复缓冲区(通过重做日志恢复数据), 清除临时表空间(用户会话信息), 整理可用空间(本地管理的表空间, 合并可用区, 将磁盘上相邻的较大的可用空间分给数据库对象)
++ 归档器(ARCn)
当重做日志文件被填满或存在日志切换时, 存档进程将一个联机重做日志文件复制归档(如果采用多路复用, 只复制归档组中的一份)(归档文件路径可在init.ora文件指定)
在系统以归档方式运行时使用(联机重做日志文件不被覆盖)
对大量更改数据库, 可以使用最多30个ARCn进程, init.ora文件中LOG_ARCHIVE_MAX_PROCESSES参数指定
当LGWR进程的写入速度快于ARCn进程的归档速度, LGWR进程会自动开启新的ARCn进程
++ 重新平衡进程(RBAL): 使用基于ASM的存储系统时调整磁盘重新平衡活动
++ ASM重新平衡(ARBn)
++ ASM平台进程(ASMB): 通过作为一个前台进程登录ASM实例与ASM实例通信
++ 可管理监控器进程(MMON): 获取最近修改的SQL对象的统计信息, 监控数据库性能, 对数据库的各种尺寸超过阈值时发出警告
++ 内存管理器(MMNL): 调整进程内部组件大小
++ 作业队列调整进程(CJQn): 任务队列执行器, 通过任务队列创建对应从属进程(J000~J999), 由从属进程执行对应的任务信息
++ 更改跟踪写入器(CTWR): 使用更改跟踪文件进行增量备份时使用
++ 恢复器(RECO): 用于调整分布式数据库
++ 内存结构
-- Oracle使用内存保存一部分程序代码和数据(刚执行和正在执行), 允许几个用户共享可执行代码
-- 数据从磁盘中读取到内存中, 并在返回到磁盘之前进行修改
-- 内存缓冲区时以页为单位的内存区域
-- Oracle内存结构分为共享的SGA(系统全局区)和PGA(进程私有内存)
-- MEMORY_TARGET参数设置总内存分配上限
-- SGA(提高查询性能, 允许大量并发数据库操作)
++ 启动Oracle实例的时候, 通过init.ora文件中指定的SGA大小分配内存
++ 数据库缓冲区高速缓存(Database Buffer Cache): 保存从数据文件中读取的数据块的副本, 当用户修改数据时这些操作也在数据库缓冲区中进行
-- 可用缓冲区(free buffer): 不包含任何可用数据
-- 脏缓冲区(dirty buffer): 包括从磁盘中读取并经过修改但还没有写入到数据文件中的数据
-- 钉住缓冲区(pinned buffer): 用户会话正在使用的数据缓冲区
当用户进程请求数据时, Oracle首先检查数据库缓冲区中是否包含数据, 如果有直接返回. 如果没有数据先从数据文件中读取到数据库缓冲区中, 如果没有free buffer可以使用, 通知DBWn进程执行写入磁盘操作
dirty buffer和pinned buffer采用LRU最近最少使用原则
数据库缓冲区高速缓存越大, 执行数据写入磁盘操作越少, 数据库性能越好. 缓存过大会导致服务器上的调页和交换
Oracle可以将数据库缓冲区高速缓存配置到多个缓冲区池中
-- 保持缓冲区池(keep): DB_KEEP_CACHE_SIZE, 始终保持在缓存中, 对频繁访问的小表可以使用
-- 回收缓冲区(recycle): DB_RECYCLE_CACHE_SIZE, 使用完数据之后马上删除, 对不频繁使用的达标可以使用
-- 默认缓冲区(nk, 8k): DB_CACHE_SIZE, 对应没有分配给keep和recycle的数据, 使用非标准块表空间时一定要创建对应的nk非标准缓冲区高速换粗的字高速缓存
n以KB为单位, 取值2, 4, 8, 16, 32
最多4个非标准的高速缓存尺寸和1个默认的标准的高速缓存尺寸(8k)
DB_2k_CACHE_SIZE=48MB
命中率=(1-物理读/逻辑读)*100, 有可能出现命中率高但是SQL查询效率低
++ 共享池(Shared Pool): 保存可执行的SQL和PL/SQL已分析过的代码和数据字典(数据表,用户,权限等元数据)高速缓存
-- 库高速缓存(library cache): 存储所有编译过的SQL语句, 用户执行的语句如果在库高速缓存中有编译过直接使用库高速缓存中的版本(软分析), 使用空间不足时会丢弃老代码
-- 数据字典高速缓存(data dictionary cache): 包括对象定义, 用户名, 角色, 权限等信息. 执行SQL之前会向判断是否有权限等, 首先会在数据字典高速缓存中查询没有才在数据文件中获取.
数据字典高速缓存未命中需要的代价远高于库高速缓存, 无法直接调整数据字典高速缓存, 只能通过调整共享池的大小而调整
共享池的命中率对性能影响远高于数据库缓冲区高速缓存
-- 结果高速缓存(result cache): 如果开启RESULT_CACHE_MODE参数, 会将SQL查询结果和PL/SQL函数执行结果缓存起来, 在重新执行的时候使用
++ 重做日志缓冲区(Redo Log Buffer): 包括通过DML操作修改信息, 通过LGWR写入到联机重做日志文件中
redo log buffer通常小于2MB. 在服务器进程在数据缓冲区高速缓冲中进行数据的删除/修改/新增的时候, 会生成对应的重做数据记录到重做日志缓冲区中. 通过LGWR进程将重做记录写入到联机重做日志文件中
通过init.ora文件的LOG_BUFFER指定重做缓冲区的大小, 运行期间不能调整大小
重做日志缓冲区写入到重做日志文件触发条件: 使用空间大于三分之一; 用户提交了一个事务; 每三秒刷新一次;使用大小超过1MB; 数据库缓冲区高速缓存写入脏数据到数据文件之前, DBWn会通知LGWR写入重做日志文件;
较大的重做日志缓冲区可以减少IO次数, 但是提交数据时消耗更多的时间
++ Java池(Java Pool): 给实例化Java对象的堆空间
包含大量Java代码的数据库, 不需要常规SGA分配给使用基于Java对象的部件
通过JAVA_POOL_SIZE指定大小
++ 大池(Large Pool): 存储大内存的配置, I/O缓冲区, 共享服务器进程(UGA), 请求队列, 响应队列
只有在数据库中使用并行查询的时候; 或者使用RMAN; 或者共享服务器配置时使用大池
通过LARGE_POOL_SIZE参数设置
++ 流池(Streams Pool): 支持Oracle流功能
可以在不同数据库之间和不同应用环境之间共享数据, 使用自动共享内存管理(MMEN)时, 大小由SGA决定不大于10%
-- PGA
++ Oracle为每个用户创建一个程序共享区保存每个用户创建的专用服务器进程的数据和控制信息
如游标得分私有值, 涉及排序分组的内存密集型操作提供内存区域, 对于大多数OLTP数据库, 事务短暂对PGA的使用率低
++ 私有SQL区域: 该内存区域保存SQL的变量绑定信息和运行时内存结构, 执行SQL语句的每一个会话都有自己的私有SQL区域
游标时私有SQL区域的句柄
++ 运行时区域: 在会话发布删除/修改/新增时创建, 在删除/修改/新增结束之后或者查询结果获取后释放
最佳方式操作: PGA中执行的分类操作完全在运行时区域中执行
单通道操作: 当PGA内存不足时, 导致分类在磁盘中进行
多通道操作: 当运行时区域太小时, 使用多通道分类数据, 高强度的磁盘操作, 效率极慢
++ 在工作量非常大的时候建议使用自动PGA管理, 不断动态调整内存界限. 手动管理容易导致分配内存过大或过小WORKAREA_SIZE_TARGET:auto/manual(手动)
使用手动管理方式时, 任何未被使用的PGA内存不会自动返回给系统. 登录到数据库的每个会话都会分配固定大小的PGA, 无论是否进行SQL操作都不会释放
++ 自动内存管理: 使用MEMORY_TARGET指定自动内存管理, 在各个SGA和PGA之间动态调整内存大小
可自动控制的部件: 数据库缓冲区高速缓存, 共享区, 大池, Java池, Streams池
必须手动控制的部件: 保持缓冲区高速缓存, 回收缓冲区高速缓存, 任何非标准块尺寸的缓冲区高速缓存, 重做日志缓冲区
使用create database创建数据库时默认为手动SGA管理, 默认PGA管理
使用DBCA创建数据库时默认为自动SGA管理, 自动PGA管理
++ 数据库事务
-- Oracle处理事务流程
1.一个用户使用Oracle net services通过3层或者多层基于web的客户机请求连接到Oracle服务器
2.在检查到该请求合法之后, 服务器为用户创建对应的专用服务器进程
3.用户执行一条把新行插入表中的语句/用户执行一条修改操作的语句
4.Oracle检查用户的权限确定是否有插入/修改的权限. 如果用户权限信息不再共享池的数据字典高速缓存中,必须从磁盘中读取到高速缓存中
5.如何用户有必须的权限. Oracle检查用户要执行的数据是否在共享池的库高速缓存中, 如果存在直接使用此版本的SQL. 如果不存在分析并执行该用户的SQL语句. 并在PGA中创建私有SQL区域
6.Oracle检查操作的数据是否在数据库缓冲区高速缓存中. 如果不存在, 则服务器进程从磁盘数据文件中读取表数据
7.Oracle对对应的表数据添加行锁
- 服务器在数据库缓冲区高速缓存中修改对的表数据(新增不需要添加到撤销表空间中, 使用rowid进行撤回)
8.服务器将更改信息写入到重做日志文件缓存中
9.修改操作需要在撤销表空间中进行记录
10.用户提交该事务, 使插入数据永久化. Oracle提交完之后释放行锁
11.LGWR立即将重做日志缓存中的数据写入到联机重做日志文件, 如果联机重做日志文件写满, ARCn进行重做日志归档
12.服务器进程发送信息给客户机进程, 说明已完成SQL操作
13.SQL操作执行之后不会马上将数据写入到数据文件. 当触发条件满足的时候, DBWn将数据从数据库缓冲区高速缓存写入到数据文件中
-- 提交
1.生成撤销信息, 由数据的前影像组成, 记录在撤销段中, 撤销段位于撤销表
2.在重做日志缓冲区中生成包含数据库和回滚块的重做日志记录. 数据库可以在提交事务前写入到磁盘中
3.更改SGA中的数据块缓冲区. 数据库可以在提交事务前写入到磁盘中
当事务提交之后
4.数据库对提交的事务分配和记录一个SCN
5.LGWR将重做日志记录从重做日志高速缓存中写入到重做日志文件中. LGWR在重做日志文件中保存SCN标记事务提交成功
6.数据库释放表锁/行锁
7.数据库标记事务为完成
-- 回滚(撤销表空间有前影像, 重做日志有完整的所有操作记录)
1.回滚原因: 用户rollback, 由于进程或者实例以非正常方式终止导致, 恢复中未提交事务的回滚, 由于语句执行错误导致的语句级回滚
2.回滚过程
++ 数据库使用撤销表空间中更改前的数据撤销事务中所作的所有更改
++ 数据库释放所有事务和表锁
++ 数据库终止事务