记住:二八法则
百分之八十的功能只用到了百分之二十的知识点。而人的时间精力是宝贵的,希望大家都可以有目标有反馈有作用的学习,让学习落地。
数据库体系结构如下(非常重要):
- Oracle由实例与数据库组成
- 用户请求顺序为:1区------->2区------>3区 或者 1区------->2区
- 实例由一个开辟的共享内存区SGA(System Global Area)和一系列后台进程组成,其中SGA最主要被划分为共享池(shared pool)、数据缓冲区(db cache)和日志缓冲区(log buffer)三类,后台进程包括PMON、SMON、LCNn、RECO、CKPT、DBWR、LGWR、ARCH等.。
- 数据库由数据文件、参数文件、日志文件、控制文件、归档文件等组成,其中归档日志最终可能会被转移到新的存储介质中,用于备份恢复使用 。
- 其中PGA(Program Global Area)也是一块共享区,与SGA不同,PGA是不共享内存的,是私有的。用户对数据库发出的查询或更新请求都在PGA中预先处理后进入SGA。其具体作用有三点:
-
- 保存用户的连接信息,如会话属性、绑定变量等;
- 保存用户权限等重要信息,当用户进程与数据库建立会话时,系统会将用户权限查询出来保存到这个回话区内;
- 当发出的指令需要排序的时候,PGA正是这个排序区,如果内存中可以完成排序就在PGA中完成,不能的话,超出的部分在磁盘中的临时表空间中完成。
举例一个普通查询执行顺序:
(select object_name from t where object_id = 29;)
用户发起请求 ---------> PGA保存用户连接和权限信息(只要不断开session,下次直接从PGA中读取),并比配一条唯一HASH值(身份证) --------> SGA共享池查看是否有HASH值,如果没有即检查语法和语义是否正确,是否有权限,没问题就存储这个HASH值。 ------> 解析语句(如:在object_id有索引的情况下估算用索引查还是全表扫描代价(COST)低用哪个)并存储执行计划(与唯一HASH值对应在一起) --------> 进入内数据缓存区查找如找不到进入数据库文件查找并将值返回
测试脚本:
drop table t; create table t as select * from all_object; create index idx_object_id on t(object_id); set autotrace on set linesize 1000 set timing on select object_name from t where object_id = 29;
set autotrace on 开启跟踪sql的执行计划和执行统计信息
set timing on 跟踪语句执行完成时间。
执行结果:
第一次
第二次
所花费的时间减少了
花费资源也少了
因为第二次不需要保存用户连接信息和权限信息,也不需要估算执行方法,而且数据已经缓存到数据缓存区,花费更低了。
举例一个普通更新执行顺序:
(update t set object_id = 92 where object_id = 29;)
查找数据流程和SELECT语句一样,不同的是之后的流程。
当数据在数据缓存区中被修改之后系统会调用DBWR进程将数据写入到DB数据文件中。
Oracle 日志系统:
Oracle日志系统记录了用户的操作信息:
A操作:建表 B操作:插入数据 C操作:更新数据
如果误更新或误删除数据,只需要执行B C操作,如果误删表,只需执行A B C操作
进程LGWR就是将日志缓存区中数据写入到数据库的日志文件中
因为日志文件数量有限,当记录满了之后,ARCH进程会将一部分日志文件备份并清空再次使用。
Oracle的COMMIT 与 ROLLBACK
Oracle中的数据是在数据缓存区中修改的,但不是确认COMMIT之后立即写入数据库中(还在缓存区),而是记录修改日志。当修改记录达到一定量级再一次性刷入数据文件中。如何防止断电内存数据消失呢?记录日志是事实存入磁盘的,所以断电之后会自动读取日志文件恢复数据。
而控制数据何时从数据缓存区存入数据库是CKPT进程决定的,但是,当LGWR进程出现问题时,DBWR进程不会听从CKPT命令将数据写入磁盘,而是等待LGWR完成。
即先有记录后有执行。
更新时,查询到相应数据到数据缓存区后,会在回滚表空间相应回滚事务表上分配事物槽,从而在回滚表空间分配到空间,该动作需要记录日志到日志缓存区;
在数据缓存区中创建未更改数据的镜像,这个镜像数据也会写入磁盘的数据文件里(回滚表空间的数据文件),也会记录日志。
之后才允许修改数据,并记录日志;
如果执行了COMMIT,日志缓存区立即记录这个提交信息,然后将回滚段事物标记为INACTIVE状态,表示允许重写;
如果执行了ROLLBACK,将回滚段的修改前镜像读取出来,修改入缓存区完成回滚。会记录日志。
DML语句特点:
由于其会改变数据库的数据。会产生将来用于恢复数据的redo和用于回退的undo。由于undo也需要保护,会有专门的保护undo的redo。
Oracle的进程介绍(核心的几个):
PMON进程(Processes Monitor):进程监视器。
如果执行更新未提交时进程崩溃了,PMON会自动回滚该操作;
如果RECO异常失败了,PMON会重启RECO进程;
如果LGWR进程失败,PMON甚至会终止这个实例等等。。。。
SMON进程(System Monitor):系统监视器。与PMON监视单个进程不同,它的工作在于 intance recovery,此外还有清理临时表空间、清理回滚段表空间、合并 空闲空间等等。。。。
LCKn进程:仅使用RAC数据库,最多10个进程(LCK0-LCK9),用于实例间的封锁。
RECO进程(Distributed Database Recovery):用于分布式数据库的恢复,适用于两阶段式提交场景。如:多个数据库A、B、C,某应用跨三个数据库,三个数据 库都提交成功才成功,否者都失败的情况。
CKPT进程:由Oracle的 FAST_START_MTTR_TARGET参数控制,用于触发DBWR进程。
DBWR进程:Oracle最核心进程之一,负责将数据从数据缓存区写入到磁盘。由CKPT进程触发,执行前会强制通知LGWR进程将日志数据写入日志文件中。
LGWR进程:Oracle最核心进程之一,将日志数据写入日志文件中。为了保证操作日志的顺序,LGWR进程是单线程的。
每隔三秒钟执行一次;
任何COMMIT触发LGWR执行一次;
DBWR将数据写入磁盘,LGWR运行一次;
日志缓冲区满三分之一或满1MB,执行一次;
联机日志文件切换也将触发LGWR。
ARCH进程:作用是当LGWR写日志,文件满了需要覆盖重写时,触发ARCH进程复制日志文件出去形成归档文件,以免日志丢失。